2014-02-15 3 views
1

파일에서 데이터를 읽고 구조체에 데이터를 저장하려고합니다. 구조체는 다음과 같습니다.파일에서 구조체로 데이터 읽기

struct someData { 
    int number; 
    char *name; 
}; 

파일의 데이터 형식은 다양 할 수 있습니다. 지금은 CSV 형식으로 읽으려고합니다. 데이터는 항상 정수 다음에 오는 문자열입니다.

some string data,100 
another string,500 

여기는 데이터를 읽고 구조체에 배치하려고하는 코드의 일부입니다.

FILE *ifp; 
char *mode = "r"; 
char *name; 
int number; 

ifp = fopen("myDataFile.txt", mode); 

if (ifp == NULL) { 
    fprintf(stderr, "Can't open input file in.list!\n"); 
    exit(1); 
} 

// read up to 100 characters up to a comma, then a decimal 
while(fscanf(ifp, "%100[^,],%d\n", name, &number) != EOF){ 

    // print out the data we got 
    printf("Data from file: %s %d", name, number); 


    struct someData *newData = (struct someData *) malloc(sizeof(struct someData)); 
    newData->number = number; 
    newData->name = name; 
    printf("Name: %s Number: %d\n\n",newData->name, newData->number); 
    } 

인쇄 문

나에게주는 두 번째 이름은 차단 실제로 이상한 문자의 몇 가지를 인쇄 끝됩니다

Data from file: some string d 100 
Name: some string d Number: 100 

Data from file: another stri Number: 500 
Name: another stri Number 500 

다음과 같습니다. while 루프에서 fscanf에 문제가 있다고 생각합니다. % 100 대신 % s를 사용하는 것과 같은 데이터를 얻으려면 몇 가지 다른 방법을 시도했지만 아무 것도 작동하지 않습니다.

+1

'char * name;'name은 배열을 가리 키지 않습니다. fscanf 전에'if' –

답변

1

당신은 char *name;char name[101];로합니다 (struct에서 안 하나)을 변경해야합니다.

그리고 당신은 변경 한 경우 더 나은 것 :

while(fscanf(ifp, "%100[^,],%d\n", name, &number) != EOF){ 

while(fscanf(ifp, " %100[^,],%d", name, &number) == 2){ 

에이 :

  • 초기 공백
  • 의 skipover는 \n 후행 삭제합니다 추가하는 언젠가는 문제를 일으킬 수있다.
  • 두 개의 유효한 인수가 읽 t 졌는지 검증합니다.

newData->name = name; 또한 작동하지 않습니다. newData->name = strdup(name);과 같은 것이 필요합니다. 또한

, 스타일의 문제로, 나는 변경 제안 :

 struct someData *newData = (struct someData *) malloc(sizeof(struct someData)); 

에 : 일부 중복 즉 "DRY"을 피할 수

 struct someData *newData = malloc(sizeof *newData); 

합니다.

그리고 절대로 newData을 저장하지 마십시오. 난 당신이 연결된 목록이나 다른 컨테이너에 추가 할 계획이 있다고 가정합니다.

또한 오류 검사를 추가해야하지만이 질문의 범위를 벗어납니다.

+1

그랬습니다! 고맙습니다! – JDD

+1

내 다음 문제였던 strdup() 팁에 감사드립니다. 그리고 네, 그 후에 나무에 들어갑니다. – JDD

+0

@ JDD : 한 점을 명확히하기 위해. 'fscanf'에있는'\ n'은 "줄 바꾸기"를 의미하지 않습니다. 이것은 "공백이 아닌 문자 또는 파일 끝이 발생할 때까지 (0 % 이상) _white-space_ 문자를 모두 먹는다"는 것을 의미합니다 ('% [...] '내의 규칙은 다릅니다). 당신이 가진 것은 잘못이 아니었지만 제 제안은 일반적으로 더 안전합니다. 하지만 내 솔루션은 여전히 ​​네임 스페이스의 _trailing_ 공백을 포함 할 수있는 잠재적 인 문제점을 가지고 있습니다. 이는 원하는 것이 아니며 문제를 일으킬 수 있습니다. 직접 제거해야합니다. '손질 '. 또한'% 100 [^, \ n]'을 사용하고 싶을 수도 있습니다. –

0

초기화되지 않은 포인터 노드를 사용 중입니다. fscanf 함수는 문자열에 대해 약간의 버퍼를 요구하며 사용자는 아무 것도 제공하지 않습니다.