2014-12-19 5 views
1

fgetc()를 사용하면 큰 문제가 있습니다. 알아낼 수는 없지만 ... 텍스트 파일을 구문 분석하려고합니다. 모든 컴파일이 실행되지만 무한 루프가 실행됩니다. xor segfault (Code :: blocks), 내 텍스트 파일은 다음과 같습니다 : { "USD_EUR": "0.8631364", "EUR_USD": "1.3964719"} 16 비율 변경. { "USD_EUR": 나는fgetc()는 float을 읽을 수 없습니다

void read(float change[4][4], char* myFile) 
{ 

    FILE* file = NULL; 
    file = fopen(myFile, "r+"); 
    int value,i; 
    float rate[16]; 
    char* str = ""; 
    if (file != NULL) 
    { 
     do 
     { 
      value = fgetc(file); 
      printf("%c \n",value); 
      while(value > 48 && value < 57) 
      { 
       value = fgetc(file); 
       strcat(str, value); 
       //printf("%s \n", str); 
      } 
      rate[i] = atof(str); 
      i++; 
      str = ""; 
     }while(value != EOF);// 125 = } 
     change[0][1] = rate[5]; 
     change[0][2] = rate[0]; 
     change[0][3] = rate[15]; 
     change[1][0] = rate[6]; 
     change[1][1] = rate[14]; 
     change[1][2] = rate[7]; 
     change[1][3] = rate[10]; 
     change[2][0] = rate[8]; 
     change[2][1] = rate[2]; 
     change[2][2] = rate[12]; 
     change[2][3] = rate[4]; 
     change[3][0] = rate[3]; 
     change[3][1] = rate[13]; 
     change[3][2] = rate[11]; 
     change[3][3] = rate[9]; 
     fclose(file); 
    } 
    else 
    { 
     printf("Unable to read the file!\n"); 
    } 
} 

나는 또한 EOF와 시도하지만 난 단지 그 루프 전 벗어나 다음 숫자 앞에 문자가 ... 속도 [16]에 내 모든 플로트를 넣어 시도 "

+1

C 문자열을 얼마나 알고 있습니까? 당신은'str = ""'할 수 없습니다. – guest

+2

그리고'strcat (char *, int)'를 호출하려고합니까? – guest

+0

에 'change'가 있으면 위치 변경 [0] [0]이 (가) 건너 뜁니다. – user3629249

답변

1

fscanf을 사용하는 것이 좋습니다.

예 다른 답변에 제공된 솔루션 외에

FILE *file; 
int i = 0, status; 
float value; 
float rate[16]; 

file = fopen(myFile, "r"); 
if(file == NULL){ 
    printf("Unable to read the file!\n"); 
    return ; 
} 
while((status=fscanf(file, "%f", &value))!=EOF){ 
    if(status==1){ 
     rate[i++] = value; 
     if(i==16)//full 
      break; 
    } else { 
     fgetc(file);//one character drop 
    } 
} 
fclose(file); 
+0

는 #define MAX_INPUTS (16)을 제안하고 그것을 코드에서 사용하고 fopen이 실패한 이유를 출력하는 것처럼 printf() 대신 perror()를 사용했습니다. 다른 좋은 코드 인 – user3629249

+0

도' 유지 정확성이라는 측면에서 생각해보십시오. – BLUEPIXY

1

문제 1 :.. 정적 문자열에 대한 포인터가이 안전하게 변경할 수 있습니다 아무것도하지 않은, 그것을 문자 그대로 메모리에 "" 포인트 str을 만들어으로

char* str = ""; 

str 선언 당신은 뭔가를 원하는 like

,
char str[30] = ""; 

문제 2와 3 :

strcat(str, value); 

시도는 안전 또는 오른쪽으로하지 않은, str에 추가 할 수 있습니다. 또한 손님 용 메모로 올바른 사용법이 아닌 strcat(char *, int)을 시도하고 있습니다. strcat(char *, char *)이 맞습니다. 참고 -이 이 아니므로 strcat(str, (char *) &value);이어야합니다. 문자열이 C에서 char 배열로 구현되는 방식, 특히 제로 터미네이션과 관련하여 이해해야합니다.

문제 4 : 위의

str = ""; 

참조 user3629249의 코멘트. 적절한 선언이 주어지면,

str[0] = '\0'; 

맞겠습니까?

문제 5 :

다시 신용으로 user3629249로 '변화'에

, 위치 변화 [0] [0]이 생략되고있다.

0

코드 시퀀스는 다음과 같습니다 'U'에

는 fgetc 결과

범위 안에 0 값이 아닌 ...배타적 9 그래서, 시도 ('I'는 공지 값으로 초기화되지 않은 경우) [I]

더 자리 이후

저장 한 STR 점을 평가하는 STR 변환을 통한 상품 STR = ""

없음을 갖는다

실행된다 : 레이트 오프셋 알려지지 []을 0 로 설정해, 'I'는 미지의 값 증가 도착 후

다음 행 (이 정의되지 않은 동작이다) 문자열에 대한 효과 (각 리터럴이 .const 섹션의 다른 위치에 있지 않는 한)

외부 루프가 반복됩니다.

결국, 범위 1에서 숯불 ... (8)는 내부 루프, 즉 제 자리 스킵되고 다른 문자가 판독되고, 그런 다음 입력

이다.

다음 예는 '.'입니다. 내부 루프가 종료 될 수 있습니다.

그러나 행 : strcat (str, value); 은 실행 파일의 .const 섹션에 쓰기 때문에 seg 오류 이벤트가 발생합니다.

1

입력 지저분 라인 직면 때 의해 제공된 라인 지향 입력 기능을 쉽게 사용할 수 있고, 읽을 libc (예 : fgets 또는 getline). 자주 (항상) libc에 의해 제공되는 다른 도구를 사용하여 데이터를 구문 분석 (예 : strtok, strsep, 등) 다른 데이터와

, 을 더 큰 유연성을 허용, 버퍼에 데이터를 한 번에 한 줄 읽기 문자 기반 입력이 더 나은 선택입니다. 귀하의 경우 라인은 수많은 '"', ':', ' '','과 인터레이스되어 있습니다. 이로 인해 fscanf 형식 문자열을 작성하여 단일 호출에서 두 환율을 모두 읽거나 strtok과 같은 문자열 구문 분석 도구를 사용하는 것은 어려웠습니다. 그래서 이것은 정말로 어려운 전화였습니다. 나는 fscanf 호출에서 float 하나의 구문 분석을위한 BluePixyes의 솔루션이 좋은 해결책이라는 데 동의합니다. 행 지향 대안은 한 번에 한 줄씩 읽은 다음 strtof을 사용하여 줄에있는 부동 소수점 값을 변환하는 것입니다. strtof이 제공하는 유일한 이점은 올바른 플로팅 변환을 확인할 수있는 변환 오류 검사입니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <limits.h> 

int main() { 

    FILE* file = NULL;    /* aways initialize variables */ 
    float rate[16] = {0.0};   /* market rates 1st & 2nd  */ 
    char myFile[50] = {0};   /* input filename    */ 
    char line[128] = {0};   /* input line buffer   */ 
    char *p = NULL;     /* pointer to parse line  */ 
    char *ep = NULL;    /* pointer to parse line  */ 
    size_t idx = 0;     /* index for rate array values */ 
    size_t it = 0;     /* general index iterator  */ 

    /* prompt for filename */ 
    printf ("\n Please enter filename to read rates from: "); 
    scanf ("%[^\n]%*c", myFile); 

    /* open & validate file */ 
    file = fopen (myFile, "r"); 
    if (!file) { 
     fprintf(stderr, "error: Unable to read the file!\n"); 
     return 1; 
    } 

    /* using line-oriented input to read line, then parse */ 
    while (fgets (line, 127, file) != NULL) 
    { 
     if (idx == 16) { 
      fprintf (stderr, "warning: array full.\n"); 
      break; 
     } 

     p = line;       /* parse line for floats */ 
     while (*p) {      /* find first digit or end */ 
      while (*p && (*p < 48 || *p > 57)) p++; 
      if (!*p) break;     /* validate not null  */ 
      rate[idx++] = strtof (p, &ep); /* get float, set end-ptr */ 
      if (errno != 0 || p == ep)  /* validate conversion  */ 
       fprintf (stderr, "discarding: rate[%zd] invalid read\n", --idx); 
      p = ep;       /* set ptr to end-ptr  */ 
     } 
    } 

    fclose (file); 

    printf ("\n The exchange rates read from file:\n\n"); 
    for (it = 0; it < idx; it++) 
     printf (" rate[%2zd] = %9.7f\n", it, rate[it]); 

    printf ("\n"); 

    return 0; 
} 

샘플 입력 :

$ cat dat/rates.txt 
"USD_EUR": "0.8631364", "EUR_USD": "1.3964719" 
"USD_AGT": "0.9175622", "EUR_USD": "1.0975372" 
"USD_BRZ": "0.8318743", "EUR_USD": "1.1713074" 
"USD_COL": "0.9573478", "EUR_USD": "1.0537964" 
"USD_GIA": "0.7904234", "EUR_USD": "1.5393454" 

출력 :

$ ./bin/read_xchgrates 

Please enter filename to read rates from: dat/rates.txt 

The exchange rates read from file: 

    rate[ 0] = 0.8631364 
    rate[ 1] = 1.3964719 
    rate[ 2] = 0.9175622 
    rate[ 3] = 1.0975372 
    rate[ 4] = 0.8318743 
    rate[ 5] = 1.1713074 
    rate[ 6] = 0.9573478 
    rate[ 7] = 1.0537964 
    rate[ 8] = 0.7904234 
    rate[ 9] = 1.5393454 

참고 : 당신의,922을 확인 이것은 라인 지향 솔루션을위한 하나의 방법입니다 컴파일러에 추가로 #define이 필요한 경우3210 매뉴얼 페이지가 필요할 수 있습니다.