【问题标题】:Reading in C line by line and storing in an array逐行读取C并存储在数组中
【发布时间】:2015-11-02 13:01:53
【问题描述】:

我正在尝试从文件列表中读取文件名并将这些名称存储在 filenames[] 数组中。

const int NUMBER_OF_FILES = 100;//here please define number of files listed in 
char* filenames [NUMBER_OF_FILES];//will contain all the file names in the list provided in List_of_input_files.txt

int counter=0;
FILE *inputfilelist = fopen("List_of_input_files.txt", "r");
char line[256];


  while(fgets(line, sizeof(line), inputfilelist)){

    filenames[counter]=line;    
    printf("%s counter: %d\n\n\n", filenames[counter], counter);
    counter++;
  }


//**************PROBLEM IS HERE***************

printf("\n\n\n\n%s Counter: 3 ", filenames[2]);// this is only to test what is inside this filename stored

fclose(inputfilelist);

输出是:

File1.txt
 counter: 0


File2.gif
 counter: 1


File3.bat
 counter: 2


File4.xml
 counter: 3


File5
 counter: 4


File6.7z
 counter: 5


File7.xlsx
 counter: 6






File7.xlsx
  Counter : 3

问题是最后一个文件名应该是 File3.bat 但不知何故它不是。 它总是显示行中的最后一个文件,即 File7.xlsx。

也许这是我正在做的一个愚蠢的错误,并且没有清楚地看到它或其他什么。我是c新手,所以我不确定。请帮忙!

已经改进并添加了要求的东西。

【问题讨论】:

  • 发布代码时,您应该检查缩进的一致性和可读性。
  • 发布List_of_input_files.txt的内容
  • 您正在将所有数据读入同一个数组,从而覆盖之前的数据。可能不是你打算做的。
  • @ITguy - 发布输入文件。此外,每次你进入 linebuffer 时,你都会覆盖之前的内容。 Filenames 是一个指针数组。所有这些指针都指向 lineBuffer。同样,lineBuffer 指向的数据会随着每次调用 fread 而改变。在使用strdup 函数从文件中读取后,您应该制作每个字符串的副本。将数组的元素设置为每次在 lineBuffer 上调用的此函数的返回值。 ;)
  • @Caleb - 实际上,它们是输入文件中的换行符。打印出用单引号括起来的字符串,很明显这就是那些 \n 的来源。

标签: c linux


【解决方案1】:

这一行

filenames[counter]=line; 

没有做你想做的事;它将line 缓冲区的地址 复制到filenames[counter];你所有的filenames[i]指向line,所以当你打印filenames[2]时,它会打印出读入line的最后一个东西。

如果您想将line内容复制到filenames[counter],您需要使用malloccalloc 分配内存来保存副本,然后复制内容使用strcpy(或使用strdup,如果有的话):

filenames[counter] = malloc( strlen( line ) + 1 );
if ( filenames[counter] )
  strcpy( filenames[counter], line );

filenames[counter] = strdup( line ); // if you have strdup available;
                                     // it's not a standard function

完成后,您需要free 每个filenames[i]

或者,您可以将filenames 数组声明为char 的二维数组:

char filenames[NUMBER_OF_FILES][256];

直接读入数组:

fgets(filenames[counter], sizeof(filenames[counter]), inputfilelist))

【讨论】:

    【解决方案2】:

    你必须分配内存来存储多个文件名。

    const int NUMBER_OF_FILES = 100;//here please define number of files listed in
    const int MAX_FILE_NAME_SIZE = 50;
    char filenames[NUMBER_OF_FILES][MAX_FILE_NAME_SIZE];//will contain all the file names in the list provided in List_of_input_files.txt
    
    int counter=0;
    FILE *inputfilelist = fopen("List_of_input_files.txt", "r");
    char line[256];
    
    
      while(fgets(line, sizeof(line), inputfilelist))
      {
    
        //filenames[counter]=line;
        strcpy(filenames[counter],line);
        printf("%s counter: %d\n\n", filenames[counter], counter);
        counter++;
      }
    
    
    //**************PROBLEM IS HERE***************
    
    printf("\n\n\n%s Counter: 3 ", filenames[2]);// this is only to test what is inside this filename stored
    
    fclose(inputfilelist);
    

    【讨论】:

    • 为什么将行读入 256 大小的缓冲区只是为了将它们复制到 50 大小的缓冲区中?建议char line[MAX_FILE_NAME_SIZE];。可能还想去掉fgets() 之后的尾随'\n'
    • @chux,我通常不会将所有错误检查都放在我提供的答案中。我相信提供最少的工作代码。我把它们留给提出问题的人作为练习。顺便说一句,我同意,代码中还有很多问题。如果我必须将它用于我的个人用途,我不会按原样使用:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2011-09-08
    • 2014-11-15
    • 1970-01-01
    相关资源
    最近更新 更多