在C中使用fwrite时int值错误

在C中使用fwrite时int值错误,c,struct,fwrite,fread,C,Struct,Fwrite,Fread,我试图用C语言为一个简单的UDP客户机-服务器应用程序创建一个密钥管理器。我在将密钥写入文本文件时遇到了问题。我目前正在将结构存储到一个txt文件中,但我的输出与使用ints时相同 // ... // if the principal is requesting to registering, store it in a file if (req.request_type == regista) { printf("Writing key to file...\n"); pFil

我试图用C语言为一个简单的UDP客户机-服务器应用程序创建一个密钥管理器。我在将密钥写入文本文件时遇到了问题。我目前正在将结构存储到一个txt文件中,但我的输出与使用ints时相同

// ...
// if the principal is requesting to registering, store it in a file
if (req.request_type == regista) {
    printf("Writing key to file...\n");
    pFile = fopen("crypt.txt", "ab");
    fwrite(&req, sizeof(struct P2Key), 1, pFile);
    printf("Written: %u %i ", req.principal_id, req.public_key);
    fclose(pFile);
    printf("Done\n");
}

// if pincipal is requesting key
if (req.request_type == request_key) {
    pFile = fopen("crypt.txt", "rb");
    printf("Key requested for: %u %i ", req.principal_id, req.public_key);
    printf("Searching for Requested Key\n");

    while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
        printf("Read: %u %i\n", res.principal_id, res.public_key);
        printf("Line Number: %ld\n", ftell(pFile));

        // if this is the client requested, send the key
        if (req.principal_id == res.principal_id) {
            send_key.principal_id = req.principal_id;
            send_key.public_key = req.public_key;
            printf("Sending Key...\n");
            // ...
        }
下面是正在写入文件的结构

typedef struct P2Key {
    enum {
        regista, request_key
    } request_type; /* same size as an unsigned int */
    unsigned int principal_id; /* client or server identifier */
    int public_key; /*  public key */
} P2Key;
尝试读取文件时获得的输出:

正在将密钥写入文件。。。
书面:27完成
...
正在将密钥写入文件。。。
书面:17完成
请求的密钥:2 7搜索请求的密钥
阅读:512 1792
电话号码:12
阅读:2561792
电话号码:24
已到达文件结尾。

我已经在这里工作了几个小时,非常感谢您的帮助。

您正在以追加模式写作;自从切换到编写结构后,您是否重新创建了该文件?您不显示甚至不测试写入的字节数,因此您不知道写入是否成功

我的第一个怀疑是,随着时间的推移,您一直在向该文件添加内容,而该文件的开头有一些与您的结构不一致的旧数据。我建议先清空文件。在UNIX/Linux上,您可以使用shell中的“>crypt.txt”来执行此操作

现在开始调试代码。捕获所有读写操作的返回值,它们返回size\u t,因此您至少可以在调试器中查看返回值。如果没有写入预期的字节数(结构的大小),则可能需要记录错误等。在调试器中单步执行写操作并关闭,然后使用十六进制转储或类似实用程序查看文件。文件中的值是否与您期望的值类似?文件包含的字节数是否与结构的大小相同


然后继续读取代码。观察代码使用fread从文件中加载每个值。注意从fread获得的返回值——它是结构的大小吗?读取完成后查看结构中的值。它看起来像是在读你写的东西吗?

你是在附加模式下写的;自从切换到编写结构后,您是否重新创建了该文件?您不显示甚至不测试写入的字节数,因此您不知道写入是否成功

我的第一个怀疑是,随着时间的推移,您一直在向该文件添加内容,而该文件的开头有一些与您的结构不一致的旧数据。我建议先清空文件。在UNIX/Linux上,您可以使用shell中的“>crypt.txt”来执行此操作

现在开始调试代码。捕获所有读写操作的返回值,它们返回size\u t,因此您至少可以在调试器中查看返回值。如果没有写入预期的字节数(结构的大小),则可能需要记录错误等。在调试器中单步执行写操作并关闭,然后使用十六进制转储或类似实用程序查看文件。文件中的值是否与您期望的值类似?文件包含的字节数是否与结构的大小相同


然后继续读取代码。观察代码使用fread从文件中加载每个值。注意从fread获得的返回值——它是结构的大小吗?读取完成后查看结构中的值。它看起来像是在读你写的东西吗?

你需要检查你的文件,因为某种原因,里面可能有一个或多个字节,这会导致你以不正确的偏移量读取结构

我的依据如下:

  • 您只需将一个结构附加到现有文件,而不管文件中当前有多少字节;及
  • 您正在读取的值是
    256
    的精确倍数。更重要的是,它们是
    256
    乘以
    1
    2
    7
    256
    512
    1792
  • 一种简单的检查方法是删除文件(或清空文件),然后再次运行程序。如果您没有任何其他写入文件的操作,它应该可以正常工作


    如果你愿意的话,实际上有很多方法可以抓住这类问题。其中包括:

    • 检查文件大小是否为打开时结构大小的精确倍数
    • 在结构中添加一个或多个用于检查每个项目的指示符字段,例如开始处的一个名为
      check\u dead
      的字段和结尾处的另一个名为
      check\u beef
      ,在写入记录时总是将其设置为
      0xdead
      0xbeef
      ,并在读取记录时始终进行检查

    您需要检查文件,由于某种原因,文件中可能有一个或多个字节,这导致您以错误的偏移量读取结构

    我的依据如下:

  • 您只需将一个结构附加到现有文件,而不管文件中当前有多少字节;及
  • 您正在读取的值是
    256
    的精确倍数。更重要的是,它们是
    256
    乘以
    1
    2
    7
    256
    512
    1792
  • 一种简单的检查方法是删除文件(或清空文件),然后再次运行程序。如果您没有任何其他写入文件的操作,它应该可以正常工作


    如果你愿意的话,实际上有很多方法可以抓住这类问题。其中包括:

    • 检查文件大小是否为打开时结构大小的精确倍数
    • 在结构中添加一个或多个用于检查每个项目的指示符字段,例如开始处的一个名为
      check\u dead
      的字段和结尾处的另一个名为
      check\u beef
      ,在写入记录时总是将其设置为
      0xdead
      0xbeef
      ,并在读取记录时始终进行检查

    您的程序似乎在这里工作。注意,我正在使用
    #include <stdio.h>
    
    typedef struct P2Key {
        enum {
            regista, request_key
        } request_type;                     /* same size as an unsigned int */
        unsigned int principal_id;          /* client or server identifier */
        int public_key;                     /* public key */
    } P2Key;
    
    void
    action(P2Key *req)
    {
        FILE *pFile;
        P2Key res;
        P2Key send_key;
    
        printf("request_type=%d regista=%d request_key=%d\n",
            req->request_type,regista,request_key);
    
    // ...
    // if the principal is requesting to registering, store it in a file
        if (req->request_type == regista) {
            printf("Writing key to file...\n");
            pFile = fopen("crypt.txt", "ab");
            fwrite(req, sizeof(struct P2Key), 1, pFile);
            printf("Written: %u %i ", req->principal_id, req->public_key);
            fclose(pFile);
            printf("Done\n");
        }
    
    // if pincipal is requesting key
        if (req->request_type == request_key) {
            pFile = fopen("crypt.txt", "rb");
            printf("Key requested for: %u %i ", req->principal_id, req->public_key);
            printf("Searching for Requested Key\n");
    
            while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
                printf("Read: %u %i\n", res.principal_id, res.public_key);
                printf("Line Number: %ld\n", ftell(pFile));
    
                // if this is the client requested, send the key
                if (req->principal_id == res.principal_id) {
                    send_key.principal_id = req->principal_id;
                    send_key.public_key = req->public_key;
                    printf("Sending Key...\n");
                    // ...
                }
            }
    
            fclose(pFile);
        }
    }
    
    int
    main(void)
    {
        P2Key req;
    
        while (1) {
            printf("Cmd (regista=%d request_key=%d): ",regista,request_key);
            fflush(stdout);
            scanf("%d",&req.request_type);
            scanf("%u %d",&req.principal_id,&req.public_key);
    
            action(&req);
        }
    }
    
    Cmd (regista=0 request_key=1): 0 5 6
    request_type=0 regista=0 request_key=1
    Writing key to file...
    Written: 5 6 Done
    Cmd (regista=0 request_key=1): 0 8 9
    request_type=0 regista=0 request_key=1
    Writing key to file...
    Written: 8 9 Done
    Cmd (regista=0 request_key=1): 1 8 9
    request_type=1 regista=0 request_key=1
    Key requested for: 8 9 Searching for Requested Key
    Read: 1 2
    Line Number: 12
    Read: 5 6
    Line Number: 24
    Read: 8 9
    Line Number: 36
    Sending Key...
    Cmd (regista=0 request_key=1): ^C