【问题标题】:Reading text file into an array in C将文本文件读入C中的数组
【发布时间】:2020-01-20 08:26:28
【问题描述】:

我想在 C 中将 .txt 文件解析为一维数组。我正在使用 fgets 函数将文件的内容读入数组(“波形”作为文件内容所在的数组存储 - 定义为“char”)。保存的值需要作为整数值保存到新数组中。我不确定我哪里出错了。 P.S:我是 C 编程新手,请多多包涵 :) 请忽略索引问题,由于粘贴完成

int main(){
    int a, win[10];

    FILE *filename = fopen("testFile.txt","r");
    char waveform[10];

    if (filename == NULL)
    {
        printf("Error opening file.\n");
        exit(8);
    }

    for(int i =0;1;i++){
        if(fgets(waveform[i], 10, filename) == NULL);
        break;

                if(i < 10)
            {
           a = atoi(waveform[i]);
           win[i] = a;
            }
         }

    fclose(filename);

    return 0; 
}

Compiler errors - image embedded

testFile.txt 中的数据: 1 到 10 个行向量。

【问题讨论】:

  • 您在if(fgets... 行有一个尾随;,不应该在那里。
  • atoi 需要一个字符串。所有的编译器错误在哪里?
  • 请回答edit问题
  • 请复制编译器错误。仅在必要时使用图片。
  • 您需要展示testFile.txt 的最小示例。

标签: c file loops for-loop fgets


【解决方案1】:

你在正确的轨道上。这是我对该主题的贡献:

  1. 打开文件 (fopen)
  2. 计算行数(getcrewind
  3. 将所有行读入数组 (getline)
  4. 释放内存并关闭文件(freefclose

代码示例:

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

int main(int argc, char *argv[])
{

  // Open File
  const char fname[] = "testFile.txt";

  FILE *fp = fopen(fname, "r");

  if( !fp )
    goto error_open_file;
  printf("Opened file: %s\n", fname); 

  // Count Lines
  char cr;
  size_t lines = 0;

  while( cr != EOF ) {
    if ( cr == '\n' ) {
      lines++;
    }
    cr = getc(fp);
  }
  printf("Number of lines: %ld\n", lines); 
  rewind(fp);

  // Read data
  {// 'goto' + data[lines] causes error, introduce block as a workaround
    char *data[lines];
    size_t n;

    for (size_t i = 0; i < lines; i++) {
      data[i] = NULL;
      size_t n = 0;

      getline(&data[i], &n, fp);

      if ( ferror( fp ) )
        goto error_read_file;

    }

    for (size_t i = 0; i < lines; i++) {
      printf("%s", data[i]);
      free(data[i]);
    }
  }

  // Close File
  fclose(fp);

  return 0;

error_read_file:
  perror("fopen ");
  return 1;

error_open_file:
  perror("getline ");
  return 2;

}

【讨论】:

  • 不客气。按照getline手册页中的说明记下对free的调用(在终端中执行man getline),它经常被遗忘。
【解决方案2】:

这个循环有几个错误

for(int i =0;1;i++){
    if(fgets(waveform[i], 10, filename) == NULL);
    break;

            if(i < 10)
        {
       a = atoi(waveform[i]);
       win[i] = a;
        }
     }

对于初学者来说,if 语句后有一个分号

    if(fgets(waveform[i], 10, filename) == NULL);
                                               ^^^

其次是 fgets 调用

fgets(waveform[i], 10, filename) 
              ^^^

无效,因为表达式 waveform[i] 的类型是 char。 而相应的这个说法

a = atoi(waveform[i]);

也是无效的。

至少应该有

fgets( waveform, 10, filename) 

a = atoi( waveform );

我假设文件的每一行都包含一个数字。 (否则,您应该使用 sscanf 来使用内部附加循环从一行中提取数字。)

循环看起来像

int i = 0;
for ( ; i < 10 && fgets( waveform, 10, filename) != NULL; i++ )
{
    a = atoi( waveform );
    win[i] = a;
}

在循环之后,变量i 将包含数组win 的实际元素数。

注意名称filename 不适用于FILE * 类型的指针。文件名是代码中的字符串"testFile.txt"

【讨论】:

  • 非常感谢您帮助我解决了很多问题 :)。我不确定您所说的“请注意名称文件名不适用于 FILE * 类型的指针。文件名是代码中的字符串“testFile.txt”。”你的意思是说“文件名”不是一个好的指针名?
  • @samz12 只是变量名不太合适。:)
  • 好的,知道了。谢谢:)
【解决方案3】:

如果您想使用fgets() 函数,您不必将其放入循环中。实际上,fgets() 的第二个参数是您要读取的元素数量。
我会将fgets() 放入单行指令中,然后使用atoi() 函数从0 循环到10 以进行从char 到int 的转换。 此外,您在if() 语句的末尾有一个;,因此您不会以您想要的方式执行它。

【讨论】:

  • 但我不确定使用单行 fgets() 是否会读取文本文件的每一行。使用单行 fgets() 后,如果我 prnt 输出,我只会得到第一个元素。
  • 根据手册页:“fgets() 从流中最多读取一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符之后停止读取。如果读取换行符,将其存储到缓冲区中。终止空字节('\0')存储在缓冲区中的最后一个字符之后。"
猜你喜欢
  • 2010-09-29
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多