【问题标题】:calling fgets twice for multiple files为多个文件调用两次 fgets
【发布时间】:2015-08-28 06:36:10
【问题描述】:

我有两个名为 id.txt 和 name.txt 的文件。

id和name的内容分别是:

12345
23456
34567
45678
56789
67890

abcde
bcdef
cdefg
defgh
efghi
fghij

问题是我必须从命令行读取输入并将其存储在一个数组中

这是我的主要代码:

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

#define MAX 10

int main(int argc, const char *argv[])
{
    char id[MAX];
    char name[MAX];

    while(fgets(id, sizeof id, stdin) != NULL)  
    {
        printf("ID: %s\n",id);
    }

    while(fgets(name, sizeof name, stdin) != NULL)
    {
        printf("Name: %s\n",name);
    }   
    return 0;
}

最后一点是我必须在命令行中重定向输入文件。

所以到目前为止我的命令行参数是:

 gcc -Wall -ansi -o main main.c     
 ./main < id.txt name.txt

输出是:

12345

23456

34567

45678

56789

67890

据我从 fgets() 了解到的是,当它到达文件末尾时,它将返回 null。因此,在读取第一个文件后,第一个 while 循环会停止,然后转到第二个 while 循环。

【问题讨论】:

  • 您在代码中使用 argv 的位置?
  • 我是否使用 argv 作为文件输入?
  • shell 重定向来自id.txt 的标准输入并将字符串name.txt 作为参数传递给您的程序。您要么需要打开以argv[1] 命名的文件,要么需要重新考虑您在做什么。传递两个文件名(如argv[1]argv[2],使用argc == 3)并打开(和关闭)这两个文件可能会更简洁。请注意,第二个循环中的 fgets() 立即返回 EOF,因为第一个循环也检测到 EOF,并且您没有使用 clearerr(stdin) 清除“错误”(EOF) 条件。但是,即使您清除了错误,您的代码也会立即获得另一个 EOF。
  • 您只是在传递文件名,但根本没有使用,您需要打开您正在传递的文件,然后根据您尝试读取 ID 和 NAME 的当前代码使用该文件描述符读取来自控制台的输入。
  • 顺便说一下,您显示的输出不是您显示的程序的输出;你错过了每一行的ID: 标签。

标签: c shell input


【解决方案1】:

您将文件名作为命令行参数传递,但未在源代码中使用。请查找以下代码以更好地理解。

并以./main id.txt name.txt 运行您的代码

argv[1]argv[2] 分别包含 id.txt 和 name.txt。

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

#define MAX 10

int main(int argc, const char *argv[])
{
    char id[MAX];
    char name[MAX];
    FILE *fp1;
    FILE *fp2;
    if(argc==3)
    {
        fp1 = fopen(argv[1],"r");
        fp2 = fopen(argv[2],"r");
        if((fp1==NULL)||(fp2==NULL))
        {
            printf("one of the file is not openend");
        }
        while(fgets(id, sizeof id, fp1) != NULL)  
        {
            printf("ID: %s\n",id);
        }

        while(fgets(name, sizeof name, fp2) != NULL)
        {
            printf("Name: %s\n",name);
        }
    }
    else
    {
        printf("Please check command line arguments");
    }
    fclose(fp1);
    fclose(fp2);
    return 0;
}

【讨论】:

    【解决方案2】:

    您可以使用file pointers 打开这两个文件然后读取它们。在命令行取文件名并执行此操作 -

     if(argc!=3){                     //check for incorrect command line arguments
           printf("Not enough arguments");
           return -1;
     }
     FILE *fp1,*fp2; 
     fp1=fopen(argv[1],"r");             //opening file in read mode
     if(fp1==NULL)                       //check return of fopen    
     {
       printf("Cannot open file %s",argv[1]);
     }
     fp2=fopen(argv[2],"r");
     if(fp2==NULL)                       //similarly check for second file
     {
       printf("Cannot open file %s",argv[2]);
     }
    

    所以while loop 中的语句应该从文件中读取,而不是从stdin 中读取。重写它们-

    while(fgets(id, sizeof id,fp1)!=NULL){
    ...
    }
    while(fgets(id, sizeof id,fp2)!=NULL){
    ...
    }
    

    还要记得最后关闭文件-

    fclose(fp1);
    fclose(fp2);
    

    【讨论】:

      【解决方案3】:

      我认为最适合您的目的不是使用标准输入,而是从命令行读取两个文件名:

      命令行是这样的

      ./main id.txt name.txt    
      

      程序(为简单起见未进行错误检查):

      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
      
      #define MAX 10
      #define MAXLINELENGTH 100
      
      int main(int argc, const char *argv[])
      {
        if (argc != 3)
        {
          fprintf(stderr, "incorrect arguments");
          exit(1);
        }
      
        FILE *input;  
        char id[MAX];
        char name[MAX];
      
        input = fopen(argv[1], "r");  // argv[1] points to "id.txt"
        while(fgets(id, sizeof id , input) != NULL)  
        {
            printf("ID: %s\n",id);
        }
        fclose(input);
      
        input = fopen(argv[2], "r");  // argv[2] points to "name.txt"
        while(fgets(name, sizeof name , input) != NULL)  
        {
            printf("Name: %s\n",name);
        }
        fclose(input);
      
        return 0;
      }
      

      【讨论】:

        【解决方案4】:

        检查代码,看看你是怎么做的。您需要 2 个文件指针,指向 2 个不同的文件。如果您想“硬编码”它,请将 argv[1] 和 argv[2] 更改为特定位置

        FILE *fp1;
        FILE *fp2;
        
        fp1 = fopen(argv[1],"r");
        fp2 = fopen(argv[2],"r");
        
        fclose(fp1);
        fclose(fp2);
        

        【讨论】:

          猜你喜欢
          • 2012-03-15
          • 1970-01-01
          • 1970-01-01
          • 2020-10-25
          • 2017-01-22
          • 2018-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多