【问题标题】:Assigning integer values from a file to an array using fgetc()使用 fgetc() 将文件中的整数值分配给数组
【发布时间】:2019-06-27 21:20:24
【问题描述】:

我想从 .csv 文件中获取数值并将它们存储在一个数组中。我的尝试可以在这里看到:

FILE *ifp;

ifp = fopen(DIREC,"r");
if(ifp == NULL){
        fprintf(stderr,"Input file not read.\n");
        exit(1);
    }

int rows = 0;
int columns = 0;

rows = readParts(ifp);
fseek(ifp, 0, SEEK_SET);
columns = readConfigs(ifp);
fseek(ifp, 0, SEEK_SET);
char arr[rows][columns];
arr[rows][columns] = malloc(sizeof(int)*rows*columns);

for (int i=0; i < rows; ++i){
        while(!feof(ifp)){
            int count = 0;
            int c = fgetc(ifp);

            if(c == '\n'){
                break;
            }
            if(isdigit(c)){
                arr[i][count] = c;
                count++;
            }
        }
    }
printf("First entry: %d", arr[0][0]);

fclose(ifp);

但是,我在使用 fgetc() 读取整数值时遇到问题。我知道它正在抓取数字,因为 printf("%c",c); 返回正确的结果。但是,将c 分配给arr 时,我没有分配正确的值,因为fgetc() 不会返回实际的字符值。我尝试投射(int) c,但它没有改变任何东西。我查看了fnscanf(),但我不确定这将如何工作,因为我的 .csv 文件还包含非数字。有没有使用fgetc() 将整数值分配给数组的正确方法?

【问题讨论】:

  • 当今大多数系统使用ASCII encoding (link)UTF-8(这是ASCII 的超集)。因此,例如,文件中看起来像零的实际上是十进制数字 48。要将数字从 ASCII 转换为数值,请使用 arr[i][count] = c - '0';
  • 这是错误的有几个原因:arr[rows][columns] = malloc(sizeof(int)*rows*columns);.
  • 你不需要调用malloc(),声明char arr[rows][columns]在本地为数组分配空间。
  • 使用fgets()读取整行,然后使用sscanf()解析数字。

标签: c arrays file io


【解决方案1】:

你有很多问题。首先:

rows = readParts(ifp);
fseek(ifp, 0, SEEK_SET);        /* rewinds to beginning */
columns = readConfigs(ifp);     /* re-reads rows values as columns */
fseek(ifp, 0, SEEK_SET);        /* rewinds to beginning -- again */

摆脱fseek(ifp, 0, SEEK_SET); 调用,只留下:

rows = readParts(ifp);
columns = readConfigs(ifp);

下一步:

char arr[rows][columns];

声明一个可变长度数组,存储空间被完全保留,不需要分配。如果要动态分配,则必须声明 rows 的指针数量,然后声明 columns 每个指针的 int 数量。 (您也可以声明指向int (*)[columns] 的VLA 的指针,但由于columns 不是编译时常量,因此不建议这样做)。删除arr[rows][columns] = malloc(sizeof(int)*rows*columns);

接下来要将文件读入数组,只需保留正确的r(行)和c(列)计数器,然后使用fscanf (ifp, "%d", &amp;arr[r][c])读取文件中的每个整数(或使用fgets()读取line int 一个缓冲区,然后使用 sscanf 解析该行中的值)

例如:

int r = 0, c = 0;

while (fscanf (ifp, "%d", &arr[r][c++]) == 1) {
    /* check if row full */
    if (c == columns) {
        r++;            /* advance row count  */
        if (r == rows)  /* protect arr bounds */
            break;
        c = 0;          /* reset column count zero */
    }
}

(注意:您提到了.csv,但没有提供文件中的任何示例输入。如果文件实际上是逗号分隔,则需要提前循环中读取的每个整数之后的读取指针(或直到找到 '\n'EOF

此时,您已经用文件中的每个整数值填充了数组,并且您已经确保每个存储的行/列值都保持在 arr 的范围内。

如果您还有其他问题,请告诉我。

【讨论】:

  • 关于:fscanf (ifp, "%d", &amp;arr[r][c]) 1) 数组应定义为:`int arr[ rows ][ columns ];所以每个条目中都有足够的空间容纳'int'值 2)这无法消耗每个整数条目之间的逗号,因此在第一次调用后会失败。
  • @user3629249 是的,是的,可以理解。没有提供样本数据。这就是为什么有一个关于此的注释:,从底部算起的第 3 段。如几天前所示,分隔符是仅逗号还是逗号前面有空格,这很重要。
猜你喜欢
  • 2012-03-02
  • 2021-12-12
  • 1970-01-01
  • 2012-03-19
  • 2021-10-13
  • 2021-07-04
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多