正确使用fwrite和fread的方法

时间:2017-04-11 14:21:43

标签: c fread

我写了一个程序

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

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

    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;
}

我试图以这种方式阅读,但我无法做到。这里有什么问题,我应该放&str[i]并为fread运行一个循环,还是fread能够将数据放入str

我得到了垃圾,我不明白为什么?

2 个答案:

答案 0 :(得分:3)

主要问题是你有fseek()向后的参数 - 你需要在(0)之前的偏移量(SEEK_SET)。第二个问题是您尝试从仅打开的文件中读取。在这种情况下,一个更小的问题,但通常非常重要的一个问题是,您不会错误地检查fopen()电话。 (此fopen()失败的可能性相对较小,但有趣的事情已经知道。)您还应该检查fwrite()电话(当然,您已经检查了fread()。)< / p>

修复所有这些可能会导致:

#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] = {'\0'};
    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系统上真正需要b模式中的"w+b",其中二进制文件和文本文件之间没有区别。如果您要在Windows上将空字节写入文件,则应使用b指示二进制模式。

如果你选择,你可以减少“灌木”。 (或嵌套深度),return函数中没有main()return EXIT_FAILURE;。您可以使用else并避免使用main()和另一组括号。如果打开文件,显示的代码小心关闭文件。在通用功能中,这很重要。在1test 1111 2222 3333 4444 1test 5555 6666 2test 5555 4444 3test 0000 4test 9999 0000 5test 3333 3333 8test 2222 9test 6666 11test 1111 中,它不那么重要,因为退出过程无论如何都会刷新和关闭打开的文件。

答案 1 :(得分:0)

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

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

"w" - 创建空文件以进行编写。如果已经有一个同名文件 存在,其内容被删除,该文件被视为新的空文件。

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

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

"w+" - 为读取和写入创建一个空文件。

"a+" - 打开一个文件进行阅读和追加。