2017-02-17 3 views
0

연습 문제가 있습니다. 나는 두 개의 구조체를 포함하는 문서 파일을 읽어야한다. 파일에서 # 문자를 읽을 때 제품이 읽는 것을 멈추어야하는 두 번째 구조체를 읽은 다음 구조체 앞에 읽기를 시작한 다음 제품을 구입해야한다. 나 좀 도와 줄 수있어?특수 문자가있는 파일에서 연결된 목록 읽기 #

구조체 파일에서 읽을 수 없으며 문자 #으로 끝납니다. 나는 두 가지가 필요하다고 생각하는데, 첫 번째 법칙은 구조체 잡지의 요소이고, 두 번째 법칙은 제품을 구조화하고 문자 #에서 멈 춥니 다.

이와 비슷한 코드를 작성할 수있는 사람이 있습니까?

(Cod_p 이름 량)

전체 만에 분리되어

별도의 행에 각 항목의 파일은, 구조체의 제품 만 라인은 동일한 행에 우주. 파일로 구성되어

은 다음과 같습니다

ENG0002
높은 거리, 8
런던
잉글랜드
SCG8888 반바지 (200)
FFSF888 셔츠 (200)
#
TRA456456
공원 도로 , 88
런던
잉글랜드
ASDASD000 반바지 (100)
ADWC000 셔츠 1000
YUAYO 신발 (122)
#


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

struct magazine { 
    char cod_m[30]; 
    char adress[30]; 
    char city[30]; 
    char nation[30]; 
    struct product* p; 
    struct magazine* next; 
    `` 
}; 

struct product { 
    char cod_p[10]; 
    char name[20]; 
    int quantity; 
    struct product* next; 
}; 

void read_st(struct magazzino* m); 

int main() { 
    struct magazzino* mag; 
    read_st(mag); 
} 

void read_st(struct magazzino* m) { 
    FILE* fp; 
    fp = fopen("magazzino.txt", "r"); 

    while (!feof(fp)) { 
     struct magazzino* m = (struct magazzino*)malloc(sizeof(struct magazzino)); 
     fscanf(fp, "%s\n%s\n%s\n%s\n", &m->cod_m, &m->adress, &m->city, &m->nation); 
     m->next; 
     printf("%s\n%s\n%s\n%s\n", &m->cod_m, &m->adress, &m->city, &m->nation); 
    } 
} 

struct prodotto* LeggiProdotto(char filename) { 
    FILE* fp = fopen("magazzino.txt", "r"); 
    while (!feof(fp)) { 
     struct prodotto* p = (struct prodotto*)malloc(sizeof(struct prodotto)); 
    } 
} 
+1

힌트 :'m-> next;'는 아무 것도하지 않습니다. 그리고 [this] (http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong)을 읽으십시오. 그리고'LeggiProdotto' 함수는 아무런 도움이되지 않지만 어쨌든 호출하지 않습니다. 그리고'fopen '한 파일을'fclose'하지 마십시오. 아마 더 많은 문제가 있습니다. –

+2

오오 그렇습니다. 실제로 어떤 문제가 있는지 언급하는 것을 잊었습니다. –

+0

파일에서 구조체를 읽을 수 없으며 문자 # – ilbranco

답변

1

이 매우 어려운 구문 분석 문제이며, fscanf()가 충분히 정교하지 않다 fscanf()은 공백을 구분 기호로 처리하므로 공백이 포함 된 문자열을 읽을 수 없습니다. 또한 fscanf으로 원하는 것을 얻지 못하면 얻은 정보를 전달하기가 어렵습니다.

대신 fgets()을 사용합니다. fgets() 문자열의 끝에 캐리지 리턴 잎

void rtrim(char *str) 
{ 
    str[strcspn(str, "\r\n")] = '\0'; 
} 

void read_magazzino(struct magazzino **m) 
{ 
    FILE* fp; 
    int finished = 0; 
    char buf[30]; 
    fp = fopen("magazzino.txt", "r"); 

    while (!finished) { 
     char *read = fgets(buf, 30, fp); 
     if (read != NULL && buf[0] != '\0') { 
      *m = malloc(sizeof(struct magazzino));  
      strcpy((*m)->cod_m, buf); 
      rtrim((*m)->cod_m); 
      fgets((*m)->adress, 30, fp); 
      rtrim((*m)->adress); 
      fgets((*m)->city, 30, fp); 
      rtrim((*m)->city); 
      fgets((*m)->nation, 30, fp); 
      rtrim((*m)->nation); 
      read_prodotto(fp, &(*m)->p); 
      m = &(*m)->next; 
     } 
     else { 
      *m = NULL; 
      finished = 1; 
     } 
    } 
    fclose (fp); 
} 

주의, 당신은 그것을 떨어져 트림 필요하므로 : 여기 fgets()를 사용 magazzino 항목의 목록을 읽는 것이 방법이다. 또한이 함수에 struct magazzino을 포인터 포인터 (struct magazzino **)로 전달했습니다. 단지 그것을 포인터로 보내면 변수를 main()에 넣으면 목록을 작성해도 영향을받지 않습니다.저는 여기에 포인터로 그것을 포인터를 만들기 위해 변수의 주소를 전달 main()에서 호출 방법은 다음과 같습니다

struct magazzino *mag; 
read_magazzino(&mag); 

이 제품을 읽으려면, 나는 fgets()을 계속 사용할 것입니다. 우리는 각 줄을 읽을 때 버퍼에있는 # 문자를 검사 할 수 있습니다. 줄에서 제품의 필드를 추출하려면 fscanf()과 비슷한 형식의 문자열을 사용하는 sscanf()을 사용했습니다. 제품 이름에 공백이 없다고 가정하면 정상이어야합니다.

void read_prodotto(FILE *fp, struct prodotto **p) 
{ 
    char buf[60]; 
    int finished = 0; 
    while (!finished) { 
     fgets(buf, 60, fp); 
     if (buf[0] != '#') { 
      *p = malloc(sizeof(struct prodotto)); 
      sscanf(buf, "%s%s%d", (*p)->cod_p, (*p)->name, &(*p)->quantity); 
      p = &(*p)->next; 
     } 
     else { 
      *p = NULL; 
      finished = 1; 
     } 
    } 
}