C 和 write() 函数 - 文件正在以十六进制写入并且写入的 int 值不正确

标签 c unistd.h

我正在尝试使用 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, &current_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 是小尾数法,bytes(不是 nybbles)必须重新排序才能以正常的左右顺序读取它们,因此值变为 00 00 03 e8。删除前导零后,您将得到十六进制的 3e8,这实际上是十进制的 1000。

这里的问题是您正在将来自 current_user_id 的字节(一个 32 位整数)按内存顺序逐个字符地写入文件。如果您希望它作为数字可读,则必须使用您选择的函数将其转换为字符串表示形式。阻力最小的途径可能是使用 fprintf() 而不是 write()

关于C 和 write() 函数 - 文件正在以十六进制写入并且写入的 int 值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41668049/

相关文章:

c - #define NAME ((LPCSTR) 5) 是什么?

c - 为什么 C 代码不返回结构?

C - 使用 lseek 向后移动文件中的指针

c++ - 将 klib 的 knetfile.c|h 移植到 Windows,当我在 "windows unistd.h"中子时,我得到错误 C2036 : 'void *' : unknown size

C:无法从文件打印

c++ - 重新分配大小未知的 const char 数组

c - 在 C 中没有获得确切的 Epoch 值

c - union 内的数据结构(C 编程)

c - 程序中的定时器太慢

c - 如何使用正确的参数在 C 中调用 execl()?