使用 fwrite 和 fread 的正确方法

correct way to use fwrite and fread

我写了一个程序

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE *fp;
    int r;
    char arr[] = "this is the string";
    char str[20] = {'[=10=]'};

    fp = fopen("fwrite.txt", "w");
    fwrite(arr, 1, sizeof(arr), fp);
    fseek(fp, SEEK_SET, 0);
    r = fread(str, 1, sizeof(arr), fp);

    if(r == sizeof(arr))
        printf("read successfully\n");
    else
    {
        printf("read unsuccessfull\n");
        exit(1);
    }

    printf("read = %d\n", r);
    printf("%s\n", str);

    fclose(fp);
    return 0;
}

我正在尝试以这种方式阅读,但我做不到。这里有什么问题,是我应该为 fread 放置 &str[i] 和 运行 循环,还是 fread 能够将数据放入 str

我越来越乱了,我不明白为什么?

主要问题是你有向后 fseek() 的参数——你需要偏移量 (0) 在 whence (SEEK_SET) 之前。第二个问题是您试图从一个只为写入而打开的文件中读取。在这种情况下,一个更小的问题,但通常非常重要,是您没有对 fopen() 调用进行错误检查。 (这个 fopen() 失败的可能性相对较小,但更有趣的事情已经为人所知。)您还应该检查 fwrite() 调用(当然,您已经检查了 fread())。

解决所有这些问题可能会导致:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int rc = EXIT_SUCCESS;
    int r;
    const char file[] = "fwrite.txt";
    char arr[] = "this is the string";
    char str[20] = {'[=10=]'};
    FILE *fp = fopen(file, "w+b");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s for reading and writing\n", file);
        rc = EXIT_FAILURE;
    }
    else
    {
        if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr))
        {
            fprintf(stderr, "Failed to write to file %s\n", file);
            rc = EXIT_FAILURE;
        }
        else
        {
            fseek(fp, 0, SEEK_SET);
            r = fread(str, 1, sizeof(arr), fp);
            if (r == sizeof(arr))
            {
                printf("read successful\n");
                printf("read = %d bytes\n", r);
                printf("read data [%s]\n", str);
            }
            else
            {
                printf("read unsuccessful\n");
                rc = EXIT_FAILURE;
            }
        }
        fclose(fp);
    }
    return rc;
}

示例运行:

$ ./fi37
read successful
read = 19 bytes
read data [this is the string]
$

请注意,这部分有效,因为您将输出字符串末尾的空字节写入文件,然后将其读回。如果文件包含空字节,则它不是真正的文本文件。在不区分二进制文件和文本文件的 Unix 系统上,"w+b" 中的 b 模式并不是真正需要的。如果要将空字节写入 Windows 上的文件,则应使用 b 指示二进制模式。

如果您愿意,可以通过在 main() 函数中不使用单个 return 来减少 'bushiness'(或嵌套深度)。您可以使用 return EXIT_FAILURE; 并避免使用 else 和另一组大括号。显示的代码在文件打开时小心关闭文件。在通用功能中,这很重要。在 main() 中,它不太重要,因为退出进程无论如何都会刷新并关闭打开的文件。

您无法使用 fopen"w" 模式读取文件,请改用 "w+"

"r" - 打开文件进行读取。该文件必须存在。

"w" - 创建一个 空文件 用于写入。如果已经有同名文件 存在,其内容被删除并且该文件被视为一个新的空文件。

"a" - 附加到文件。写操作,在末尾追加数据 文件。如果文件不存在,则创建该文件。

"r+" - 打开文件以同时更新读写。该文件必须存在。

"w+" - 创建一个用于读写的空文件。

"a+" - 打开文件进行读取和追加。