2013-08-12 3 views
1

제가 만들고있는 프로그램은 텍스트 파일의 숫자를 읽고 구조체에있는 숫자의 평균 값을 저장합니다.C : 텍스트 파일에서 구조체 배열로 읽어들입니다.

나는 다음과 같다 구조체를 가지고 :

struct seriepost { 
    int totnr; 
    int outnr; 
    float average; 
}; 

그리고 (미완성) 기능은 다음과 같습니다 :

텍스트 파일은 다음과 같습니다
int read_data(FILE *tsin, struct seriepost serie[]) { 

     int x = 0; 
     float average = 0; 
     float in_last = 0; 
     while (!feof(tsin)) 
     { 
      while (fscanf(tsin, "%f", &in_last) != 0.0) 
      { 
      serie[x].totnr += 1; 
      serie[x].medel = average/serie[x].totnr; 
      serie[x].outnr = average*1.05+average*0.95; 
      } 
      x += 1; 
     } 
     fclose(tsin); 
     return sizeof(serie); 
    } 

:

22.2 12.4 24.5 12.4..... 
22.2 12.2 0.0 

2.21 12.1 11.1 11.1.... 
1.1 0.0 

여기서 0.0은 계열의 끝을 나타냅니다.

이제 fscanf가 0.0까지 모든 숫자를 읽은 다음 다음 시리즈의 다음 배열 지점으로 건너 뛰기를 원합니다. 그래서 serie [0], serie [1]처럼 숫자와 평균값 등을 가지고 있습니다.

+0

+1. 웹에서 사용할 수있는 리소스를 훌륭하게 사용합니다! 토마스,이게 과제 번호 7 번이었던 코스의 선생님 이오. –

답변

2

reference of fscanf이 표시되면 성공적으로 스캔 한 항목의 수를 반환합니다. 당신이 방금 스캔 한 가치.

즉, 결말 조건을 다르게 확인해야합니다.

while (!feof(...))을 루프하지 않아야합니다. 파일 끝을 초과하여 이미 읽으려고 할 때까지 파일 끝 조건이 설정되지 않기 때문입니다.

while (fscanf(tsin, " %f", &in_last) > 0) 
{ 
    if (in_last == 0.0f) 
     ++x; 
    else 
    { 
     /* The rest of your code */ 
    } 
} 

이것은 당신이 파일의 마지막에 도달하거나 오류가있을 때까지 읽고, 당신이 0.0을 읽을하면 인덱스를 증가 :

대신 당신이 뭔가를 할 수 있습니다. fscanf 형식 문자열의 선행 공백은 fscanf이 공백 (공백, 탭, 줄 바꿈)을 건너 뜁니다.


코드에 몇 가지 다른 문제가 있습니다. 예를 들어, average 변수를 업데이트하지 마십시오. serie[x].totnr의 값은 초기화되지 않을 수 있으므로이 값을 늘리면 (일반적으로 연산에서 사용하는 경우)이 경우에는 정의되지 않습니다. 그리고 나서 series은 함수의 배열이 아니라 포인터이기 때문에 sizeof 연산자는 배열의 항목 수가 아니라 포인터의 크기를 반환하므로 작동하지 않는 sizeof(series)을 사용합니다. 대신 배열의 크기 인 x을 반환하십시오.

+0

오, 나는 fscanf가 어떻게 일했는지 완전히 오해했다. 당신의 코드는 정말 좋고 이해하기 쉽기 때문에 나를 어리 석 게 느낍니다. 도와 주셔서 감사합니다! – user2674975

0

fscanf은 값이 아니라 성공적으로 읽은 항목의 수를 반환합니다.

while (fscanf(tsin, "%f", &in_last) != 0.0) 

은 다음과 같아야합니다
while (fscanf(tsin, "%f", &in_last) != 1) 

은 또한 당신이 상수 값에 대해 float을 비교할 수 없습니다. 대부분의 경우 작동하지 않습니다. 따라서 델타를 선택하고 플로트가 그 범위 내에 있는지 확인해야합니다.

전화 할 때 이미 알고있는 상수이기 때문에 sizeof(serie)도 보내지 않으려한다고 생각합니다.읽은 값의 수를 나타내려면 x-1을 반환 할 가능성이 큽니다. feof 조건이 충족되면 아무 것도 읽지 않고 x가 1이됩니다 (루프 때문에).

BTW : 텍스트 파일에 고정 된 크기의 줄이없고 배열의 크기를 미리 알고 있으면 프로그램에 문제가있을 수 있습니다. 읽는 동안 배열을 할당하지 않지만 alerady를 전달하면 x가 증가하면 배열이 오버런 될 수 있습니다.

관련 문제