【问题标题】:Reading float numbers from a file in a special manner以特殊方式从文件中读取浮点数
【发布时间】:2017-08-01 21:53:08
【问题描述】:

我正在尝试从二维数组中的文件中读取数字,我必须跳过第一行和第一列,其余的都必须保存在一个数组中,我尝试过使用 sscanf、fscanf 甚至 strtok () 但惨遭失败。所以请帮我解决这个问题。 提前谢谢,

Link to the file

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]){
FILE *f=fopen("Monthly_Rainfall_Himachal.txt","r");
float data[12][12];
int i,j;
char newLine[1000];
fgets(newLine,1000,f);
char* item,waste;
i=0;
while(1)//read file line by line
{
    fscanf(f, "%s %f %f %f %f %f %f %f %f %f %f %f %f ", waste, &data[i][0], &data[i][1], &data[i][2], &data[i][3], &data[i][4], &data[i][5], &data[i][6], &data[i][7], &data[i][8], &data[i][9], &data[i][10], &data[i][11]);
    i++;
    if(feof(f))break;
}
fclose(f);

for(i=0 ;i<12 ;i++){
    for(j=0 ;j<12 ;j++){
        printf("%.1f\t",data[i][j]);
    }
    printf("\n");
}
return 0;
}

【问题讨论】:

  • 为什么不检查fscanf的返回值?
  • char waste 是单个 char%s 格式需要一个数组。即使它是char* waste(如您所想)也没有分配内存。

标签: c file-io floating-point scanf


【解决方案1】:

问题:

  1. 您不检查fopen 是否成功打开文件并盲目假设它确实成功了。

    检查它的返回值:

    if(f == NULL)
    {
        fputs("fopen failed! Exiting...\n", stderr);
        return EXIT_FAILURE;
    }
    
  2. 您可以使用scanf 读取并丢弃第一行,而不是读取并存储第一行:

    scanf("%*[^\r\n]"); /* Discard everything until a \r or \n */
    scanf("%*c");       /* Discard the \r or \n as well */
    
    /* You might wanna use the following instead of `scanf("%*c")` 
       if there would be more than one \r or \n 
    
    int c;
    while((c = getchar()) != '\n' && c != '\r' && c != EOF);
    
       But note that the next fscanf first uses a `%s` which
       discards leading whitespace characters already. So, the
       `scanf("%*c");` or the while `getchar` loop is optional 
    */
    
  3. 您有一个未使用的字符指针item 和一个字符变量waste。这两个都是不必要的。所以,删除它们。
  4. 在很长的fscanf 行中,您首先尝试将字符串扫描到调用未定义行为的字符变量中,然后事情变得混乱。还需要检查它的返回值是否成功。

    fscanf 行替换为以下内容:

    if(fscanf(f, "%*s") == EOF)
    {
        fputs("End Of File! Exiting...\n", stderr);
        return EXIT_SUCCESS;
    }
    for(j = 0; j < 12; j++)
    {
        if(fscanf(f, "%f", &data[i][j]) != 1)
        {
            fputs("End Of File or bad input! Exiting...\n", stderr);
            return EXIT_SUCCESS;
        }
    }
    
  5. 您假设输入最多为 12 行,但如果它包含超过 12 行,您的代码将由于数组溢出而调用未定义行为。

    检查ifeof 的值,确保它不超过11​​:

    if(i >= 12 || feof(f))
    

注意:我没有测试任何上述代码。如果我犯了错误,请纠正我。谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2011-05-09
    相关资源
    最近更新 更多