C 和 write() 函数 - 文件正在以十六进制写入并且写入的 int 值不正确
C and write() function - File is being written in hexadecimal and written int value is not correct
我正在尝试使用 write()
函数(包含在 <unistd.h>
中)写入文件。该程序很简单:当 运行 可执行文件时,我键入一条消息,然后将消息和我的用户 ID (Linux UID) 保存到文件中。
$ ./notetaker "Hello"
我原以为可以将以下值保存到文件中:
1000
Hello
有两个问题:
- 我的文件是用十六进制写的(当我用 Sublime Text 打开它时,我只能看到十六进制值)
- 插入的代表我的用户 ID 的整数不正确
这是我在 运行 cat notes.txt
:
时得到的结果
�
Hello
当我用 Sublime Text 打开 notes.txt 文件时,我可以读取以下数据:
e803 0000 0a48 656c 6c6f 0a
前4个字节不等于“1000”。
为什么我的文件保存为十六进制值?为什么数字不正确?
这是我的源代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
void write_uid(const int);
void write_note(const int, void *);
int main(int argc, char *argv[])
{
char *buffer = (char *) malloc(100);
if(buffer == NULL) exit(0);
strcpy(buffer, argv[1]);
char *filename = (char *) malloc(50);
if(filename == NULL) exit(0);
strcpy(filename, "notes.txt");
int file_descriptor = open(filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
if(file_descriptor == -1) exit(0);
write_uid(file_descriptor);
write_note(file_descriptor, buffer);
if(close(file_descriptor) == -1) exit(0);
printf("Your note has been saved successfully. \n");
free(buffer);
free(filename);
return 1;
}
void write_uid(const int file_descriptor)
{
int current_user_id = getuid();
int uid_write_result_code = write(file_descriptor, ¤t_user_id, sizeof(current_user_id));
int new_line_write_result_code = write(file_descriptor, "\n", 1);
if(uid_write_result_code < 0 || new_line_write_result_code < 0)
exit(0);
}
void write_note(const int file_descriptor, void *buffer)
{
int note_write_result_code = write(file_descriptor, buffer, strlen( (char *) buffer ));
int new_line_write_result_code = write(file_descriptor, "\n", 1);
if(note_write_result_code < 0 || new_line_write_result_code < 0)
exit(0);
}
我使用的是 Ubuntu 14.04 Trusty Tahr (x64),我的 GCC 版本是 4.8.4。此外,使用 -Wall 选项进行编译时,不会显示任何警告。
您的数值 1000 是前 4 个字节:e8 03 00 00
.
Intel CPU 是 little-endian, 字节 (不是 nybbles)必须重新排序才能以正常的 left-right 顺序读取它们,因此值变成 00 00 03 e8
。删除前导零会使您成为十六进制的 3e8
,这实际上是十进制的 1000。
您的问题是您正在将 current_user_id
中的字节按内存顺序写入您的文件 character-by-character,这是一个 32 位整数。如果您希望它是 human-readable 作为数字,则必须使用您选择的函数将其转换为字符串表示形式。阻力最小的路径可能是使用 fprintf()
而不是 write()
。
您必须格式化结果,否则它将以原始二进制格式写入。使用 fprintf
(file print formatted)。或者,如果您正在使用写入,则使用 sprintf
格式化整数以获得该整数的等效字符串表示,然后保存字符串。
char str[20];
sprintf(str, "%i\n", current_user_id);
write(file_descriptor, str, strlen(str));
// no needto write \n, it's already included in str
我正在尝试使用 write()
函数(包含在 <unistd.h>
中)写入文件。该程序很简单:当 运行 可执行文件时,我键入一条消息,然后将消息和我的用户 ID (Linux UID) 保存到文件中。
$ ./notetaker "Hello"
我原以为可以将以下值保存到文件中:
1000
Hello
有两个问题:
- 我的文件是用十六进制写的(当我用 Sublime Text 打开它时,我只能看到十六进制值)
- 插入的代表我的用户 ID 的整数不正确
这是我在 运行 cat notes.txt
:
�
Hello
当我用 Sublime Text 打开 notes.txt 文件时,我可以读取以下数据:
e803 0000 0a48 656c 6c6f 0a
前4个字节不等于“1000”。
为什么我的文件保存为十六进制值?为什么数字不正确?
这是我的源代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
void write_uid(const int);
void write_note(const int, void *);
int main(int argc, char *argv[])
{
char *buffer = (char *) malloc(100);
if(buffer == NULL) exit(0);
strcpy(buffer, argv[1]);
char *filename = (char *) malloc(50);
if(filename == NULL) exit(0);
strcpy(filename, "notes.txt");
int file_descriptor = open(filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
if(file_descriptor == -1) exit(0);
write_uid(file_descriptor);
write_note(file_descriptor, buffer);
if(close(file_descriptor) == -1) exit(0);
printf("Your note has been saved successfully. \n");
free(buffer);
free(filename);
return 1;
}
void write_uid(const int file_descriptor)
{
int current_user_id = getuid();
int uid_write_result_code = write(file_descriptor, ¤t_user_id, sizeof(current_user_id));
int new_line_write_result_code = write(file_descriptor, "\n", 1);
if(uid_write_result_code < 0 || new_line_write_result_code < 0)
exit(0);
}
void write_note(const int file_descriptor, void *buffer)
{
int note_write_result_code = write(file_descriptor, buffer, strlen( (char *) buffer ));
int new_line_write_result_code = write(file_descriptor, "\n", 1);
if(note_write_result_code < 0 || new_line_write_result_code < 0)
exit(0);
}
我使用的是 Ubuntu 14.04 Trusty Tahr (x64),我的 GCC 版本是 4.8.4。此外,使用 -Wall 选项进行编译时,不会显示任何警告。
您的数值 1000 是前 4 个字节:e8 03 00 00
.
Intel CPU 是 little-endian, 字节 (不是 nybbles)必须重新排序才能以正常的 left-right 顺序读取它们,因此值变成 00 00 03 e8
。删除前导零会使您成为十六进制的 3e8
,这实际上是十进制的 1000。
您的问题是您正在将 current_user_id
中的字节按内存顺序写入您的文件 character-by-character,这是一个 32 位整数。如果您希望它是 human-readable 作为数字,则必须使用您选择的函数将其转换为字符串表示形式。阻力最小的路径可能是使用 fprintf()
而不是 write()
。
您必须格式化结果,否则它将以原始二进制格式写入。使用 fprintf
(file print formatted)。或者,如果您正在使用写入,则使用 sprintf
格式化整数以获得该整数的等效字符串表示,然后保存字符串。
char str[20];
sprintf(str, "%i\n", current_user_id);
write(file_descriptor, str, strlen(str));
// no needto write \n, it's already included in str