2017-03-11 9 views
0

2次元配列のファイルから数値を読み取ろうとしていますが、最初の行と最初の列をスキップする必要があり、残りはすべて配列に保存する必要があります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; 
} 
+2

なぜ、fscanfの戻り値をチェックしないのですか? –

+1

'char waste'は単一の' char'ですが、 '%s'形式は配列を必要とします。それでも、それは(あなたが想像するように) 'char * waste'でした。割り当てられたメモリはありません。 –

答えて

3

問題:

  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の以上の行が含まれている場合は、あなたのコードが原因に未定義の振る舞いを呼び出しますアレイオーバーラン。

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

注:私は上記のコードのいずれかをテストしていない

は、それが11を超えないことを確認するfeofとともにiの値を確認してください。私が間違えた場合は、私を修正してください。ありがとう!

関連する問題