逐行阅读

时间:2016-01-02 19:15:48

标签: c find line fgets

我有一个带有一些文件名及其大小的txt文件。 这就是我写txt文件的方式:

banana //file name
3 //the size of file banana
programs
12
music
524

我必须找到键盘输入的文件名并显示它的大小。

这是我的代码:

 FILE *text;
 text=fopen("text.txt","r");
 printf("Scan the number of letters of your file name");
 int n;
 scanf("%d",&n);
 char s[++n];
 printf("Scan the file name you are looking for: ");
 int i;
   for(i=0;i<=n;i++)
   {
       scanf("%c",&s[i]);
   }
 int l=0;
 char c[n];
 char g;
   while(!feof(text))
   {
       if(l%2==1) {fgetc(text); fgetc(text); l++;}
       if(l%2==0)
       {
         fgets(c,n,text);
         fgetc(text);
           for(i=0;i<n;i++)
           {
             printf("%c",c[i]);
           }
           l++;
       }
   }

显然,这不正确。你能帮助我吗?我有点困惑。

1 个答案:

答案 0 :(得分:1)

唉!请详细了解基本输入。你的程序有各种缺陷:

  • fgetc读取单个字符。这有时很有用,但显然你想读整行。 fgets这样做。你使用它一次,但不建议将它们混合使用。首先确定要使用的输入范例:char-wise(fgetc),line-wise(fgets)或token-wise(fscanf)。
  • 请不要让用户输入文件名中的字符数。快速,MySpiffyDocument.txt中有多少个字符?这是计算机应该做的工作。
  • 不要使用feof来控制yopur输入。所有输入函数都有特殊的返回值,表示文件末尾已被读取或发生错误。对于fgets,此返回值为NULL,对于fgetc,此返回值为特殊常量EOF。在遇到两个结束条件的 post mortem 分析的特殊返回值后,函数feofferror非常有用。
  • 你的内部循环,负责核心程序逻辑,根本没有意义。例如,对于奇数l,请增加l,然后测试偶数l - 这将是真的,因为您刚刚建立了一个奇数l。在这种情况下使用else。并且不要在条件块中放置任何事情:在l / if块后增加else

以下是一个示例实现:

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

int process(const char *filename)
{
    char line[80];
    char name[80];
    int size;
    int count = 0;

    FILE *f = fopen(filename, "r");

    if (f == NULL) return -1;

    while (fgets(line, sizeof(line), f)) {
        if (count % 2 == 0) {
            if (sscanf(line, "%s", name) < 1) continue;
        } else {
            if (sscanf(line, "%d", &size) < 1) continue;
            printf("%12d   %s\n", size, name);
        }

        count++;
    }
    fclose(f);

    return 0;    
}

int main()
{
    char line[80];
    char name[80];

    puts("Please enter filename:");

    while (fgets(line, sizeof(line), stdin)) {
        if (sscanf(line, "%s", name) == 1) {
            process(name);
            break;
        }
    }

    return 0;
}

注意事项:

  • 该程序最多使用80个字符。缓冲区大小;这意味着您的行最多可包含78个字符 - 行内容加上新行'\n'加上空终止符'\0'。在许多情况下这应该没问题,但最终线路可能会溢出。 (所以你的文件名字母有一些优点,但真正的解决方案是动态分配内存。我现在不会打开那些蠕虫。)
  • 代码使用双重策略:首先读取行,然后使用sscanf扫描这些行,以便只读取每行的第一个单词。
  • 跳过空行。即使是没有有效号码的行也会被跳过。这是错误的错误处理,可能会使奇数/偶数计数。
  • 在C中以交互方式阅读内容在C中非常简单。fgets中的笨拙sscanf / main构造试图处理用户输入空的情况通过Ctrl-D / Z排出或唤醒文件结束信号。更好更简单的方法是通过argcargv为命令行提供参数。
  • 我已将文件读取移动到单独的功能中。