2017-03-11 8 views
0

2D 배열의 파일에서 숫자를 읽으려고합니다. 첫 번째 행과 첫 번째 열을 건너 뛰고 나머지는 모두 배열에 저장해야합니다. '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 개 이상의 라인이 포함 된 경우, 코드가 인해로 정의되지 않은 동작을 호출합니다 배열 오버런. feof과 함께 i의 값이 11을 넘지 않는지 확인하는

    확인 :

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

참고 : 나는 위의 코드 중 하나를 테스트하지 않았다. 내가 실수를 범하면 저를 시정하십시오. 감사!