我在C语言中的程序仅读取第一行。我试图让它读取文本文件的所有内容

时间:2019-01-27 01:29:52

标签: c

我有一个类似的程序,它将毫无问题地读取整个文本文件。但是也许这就是我在这里拥有fscanf的方式吗?第一次我遇到这样的事情。基本上,我是将文件中的第一个字符串存储到变量中,然后尝试使用它来遍历第二个文件中的每一行,以查看字符串是否存在。

#define MAX_LENGTH 500
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



int main() {

        char string1[MAX_LENGTH]; //this will each string from my first file to compare every string in the second file
        char string2[MAX_LENGTH];
        int result;

        FILE *fp1;
        FILE *fp2;
        fp1 = fopen("C:/textfile1.txt", "r");
        fp2 = fopen("C:/textfile2.txt", "r");

        if (fp1 == NULL || fp2 == NULL) {

            printf("FILE cannot be opened... exiting...");
            exit(1);

        }

        //while (1) {

            while(! feof(fp1)) { 

                fscanf(fp1, "%[^\n]s", string1); 

                while (! feof(fp2)) {

                    fscanf(fp2, "%[^\n]s", string2); 
                    result = strcmp(string1, string2);

                    if (result == 1) { 

                        printf("%s has been ADDED...\n", string1);

                    }
                }

            }

            while(! feof(fp2)) {

                fscanf(fp2, "%[^\n]s", string1);

                while (!feof(fp1)) {

                    fscanf(fp1, "%[^\n]s", string1);
                    result = strcmp(string2, string1);

                    if (result == 1) {

                        printf("%s has been REMOVED...\n", string2);
                    }
                }

            }
        //}

        getchar();
        getchar();

        return 0;

}

2 个答案:

答案 0 :(得分:1)

首先,让我首先说fscanf()并不是您正在执行的理想功能,请使用fgets()getline(),正如其他人已经说过的那样。其次,您应该注意到程序中的最后两个while语句将被跳过,因为到执行流到达该点时,流fp2fp1都已经在EOF上。

现在,关于您的问题,您的问题是以下模式:"%[^\n]s"如果您打算阅读一行文本,则不需要尾随's',它将需要输入流在's'

匹配的序列之后包含%[^\n]

%[^\n]模式的意思是“读取所有内容,直到第一个'\n',但不包括'\n'本身,它会留在缓冲区中;这不好,一旦下一个fscanf()调用将读取剩下的'\n',仅此而已,要解决此问题,您需要清理缓冲区,类似fscanf(fp, "%*c")的方法应该起作用。备用'\n'字符,则每次调用fscanf()后都需要这样做。

        while(! feof(fp1)) { 

            fscanf(fp1, "%[^\n]", string1);
            fscanf(fp1, "%*c");

            printf("%s\n", string1);

            while (! feof(fp2)) {

                fscanf(fp2, "%[^\n]", string2);
                fscanf(fp2, "%*c");

                printf("%s\n", string2);

                result = strcmp(string1, string2);

                if (result == 1) { 

                    printf("%s has been ADDED...\n", string1);

                }
            }
        }

答案 1 :(得分:1)

  

..继续只读取第一行。

fscanf(fp1, "%[^\n]s", string1);无法读取'\n'

由于代码从不读取'\n',因此它将保留在文件中,直到某些代码读取它为止。随后不会读取文件。


fscanf(fp1, "%[^\n]s", string1);出于其他原因也很糟糕。

1)没有宽度限制。输入过多会导致不确定的行为(UB)。通常是 other 数据损坏。

2)"s"无用。放下它。

3)未检查返回值fscanf()。代码不知道向string1中写入了什么。


替代:使用fgets()

        // Avoid
        // while(! feof(fp1)) { 
        //    fscanf(fp1, "%[^\n]s", string1); 
        //    while (! feof(fp2)) {
        //        fscanf(fp2, "%[^\n]s", string2); 

        while(fgets(string1, sizeof string1, fp1)) {
            string1[strcspn(string1, "\n")] = '\0';  // Lop off potential \n
            while(fgets(string2, sizeof string2, fp2)) {
                string2[strcspn(string2, "\n")] = '\0';