从C语言中读取和写入文件

时间:2017-04-07 20:15:34

标签: c file fgets

拜托,有人能解释一下为什么这个程序不起作用? 我正在尝试使用r+从文件中读取和写入。文件test.txt存在,写入正确执行。但是,阅读不起作用。

int main() {

    FILE* fichier = NULL;
    int age, TAILLE_MAX=10;
    char chaine[TAILLE_MAX];

    fichier = fopen("test.txt", "r+");
    if (fichier != NULL)
    {

        printf("give your age ? ");
        scanf("%d", &age);
        fprintf(fichier, "Hello you have %d year old", age);

        while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
        {
            printf("%s", chaine); //does not print
        }fclose(fichier);
    }

    return 0;
}

通过不起作用我的意思是它不显示任何东西!即使文件中包含一些你已经...的句子。没有错误。只是该程序不打印文件的内容

2 个答案:

答案 0 :(得分:1)

你正在同时写作和阅读文件, 这不是好习惯, 但是你的代码不起作用的原因是因为缓冲。在fprintf(fichier, "Hello you have %d year old", age);声明发生之前,fclose(fichier)可能不会发生。 我在代码中添加了两个语句,见下文。 另外,一旦你执行了fprintf文件指针fichier不在文件的末尾,这是你尝试做的下一件事的错误位置,你可以阅读age号码刚写了,所以你必须以某种方式移回文件指针fichier - 我只使用rewind,如果test.txt是新创建的文件,它将起作用。否则,您将需要一些向后移动文件指针fichier的方法,以便阅读您刚才写的内容。

int main() {

FILE* fichier = NULL;
int age, TAILLE_MAX=10;
char chaine[TAILLE_MAX];

fichier = fopen("test.txt", "r+");
if (fichier != NULL)
{

    printf("give your age ? ");
    scanf("%d", &age);
    fprintf(fichier, "Hello you have %d year old", age);

    fflush( fichier );  /* force  write to FILE */
    rewind( fichier );  /* rewind FILE pointer to beginning */

    while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
    {
        printf("%s", chaine); //does not print
    }
}
fclose(fichier);
return 0;
}

在您的原始代码中,声明

while (fgets(chaine, TAILLE_MAX, fichier) != NULL)

无法读取任何内容并返回NULL,因此printf("%s", chaine);将不会发生。发生这种情况是因为输出缓冲和fprintf()语句没有在您认为应该发生时发生。

此输出缓冲是正常的,如果您希望在该确切时刻发生printf,则需要使用fflush() 阅读此处以了解更多信息:Why does printf not flush after the call unless a newline is in the format string?

答案 1 :(得分:1)

问题是您在写完文件句柄后尝试阅读文件句柄。

fichier就像编辑器中的光标,它只在文件中有一个位置。当您使用r+ fichier打开文件时,该文件位于文件的开头。当您打印到fichier时,它会覆盖文件开头的所有内容。然后,当您尝试阅读时,它会从打印机停止的位置读取。

例如,如果我开始test.txt中包含一些文字,特别是将会打印更多文字。

$ cat test.txt
First line
Second line
Third line

然后我运行程序。

$ ./test
give your age ? 41
rd line

请注意它打印rd line,因为它在写Hello you have 41 year old后遗留了什么。

$ cat test.txt
Hello you have 41 year oldrd line

我不确定您要完成的任务,但您可能需要fseek才能将光标移动到正确的位置。

作为旁注,将整个程序包装在if (fichier != NULL)中是很尴尬的。如果文件没有打开,你就没有错误信息,它将悄然而神秘地无所事事。而是检查错误,显示信息性消息,然后退出程序。

#include <string.h>
#include <errno.h>
#include <stdlib.h>

char file[] = "test.txt";
FILE *fichier = fopen(file, "r+");
if (fichier == NULL) {
    fprintf(stderr, "Could not open '%s' for r+: %s\n", file, strerror(errno));
    exit(1);
}

这被称为early exit,使代码变得更加简单。通过立即处理错误,代码可以遵循happy path而无需始终嵌套在条件中。