2016-09-17 4 views
0

다음 코드를 사용하여 이진 파일을 읽고 구조체를 사용하여 데이터를 출력합니다. 그러나, 나는 나의 자료가 단지 하나의 기록으로 이루어져 있다는 것을 안다. 그리고 그것은 많은 기록을 인쇄하고있는 것처럼 보인다. 왜이게 될지 궁금하네요?구조체를 사용하여 이진 파일을 읽고 레코드를 찾습니다.

FILE *p; 
struct myStruct x; 
p=fopen("myfile","rb"); 
//printf("Rcords of file:\n"); 
while(1) 
{ 
    fread(&x,sizeof(x),1,p); 
    if(feof(p)!=0) 
     break; 
     printf("\n\nID:%ld",x.ID); 
    } 
fclose(p); 
return 0; 

구조체는 다음과 같이 매우 정상입니다 :

struct myStruct 
{ 
    int ID;  
    char name[100]; 
} 
+1

'char name;'의미가 없습니다. 이름은 거의 단일 문자로 구성되지 않습니다. –

+0

ok ive 업데이트 - 지금 만족하십니까? –

+1

파일의 크기는 어느 정도입니까? ['fread'] (http://en.cppreference.com/w/c/io/fread)는 무엇을 반환합니까? –

답변

2

사용 %d 대신 %ldint

를 인쇄하고 struct는 고정을 가진 사람들 Why is “while (!feof (file))” always wrong?

을 살펴보고 크기, ftell을 사용하여 파일 크기를 가져올 수 있습니다. e를 입력 한 다음 struct의 크기를 사용하여 레코드 수를 얻고 그 함수의 결과를 항상 확인하십시오. 같은

뭔가 :

FILE *file; 
long size; 
size_t count, records; 

file = fopen("myfile", "rb"); 
if (file == NULL) { 
    perror("fopen"); 
    return 0; 
} 
if (fseek(file, 0, SEEK_END) == -1) { 
    perror("fseek"); 
    return 0; 
} 
size = ftell(file); 
if (size == -1) { 
    perror("ftell"); 
    return 0; 
} 
if (fseek(file, 0, SEEK_SET) == -1) { 
    perror("fseek"); 
    return 0; 
} 
records = size/sizeof(x); 
for (count = 0; count < records; count++) { 
    if (fread(&x, sizeof(x), 1, file) == 1) { 
     printf("\n\nID:%d",x.ID); /* %d instead of %ld */ 
    } else { 
     break; 
    } 
} 

그러나 당신은 항상 스택에 같은 변수에 작성하는 것을 알 수 있습니다.

편집 :

당신은 어떻게 파일의 struct를 저장합니까?

나는 프로그램을 저장하지 않습니다.

가 당신 아닌 경우이 파일 내부의 sizeof(x) 어떤 알 수 없다 (같은 struct을 사용하여 파일을 작성하지 않음), 구조 패딩 및 포장에 대해 읽어보십시오.

+0

hmmn x는 어디에 생성 되었습니까? –

+1

hmmm 최소한, 완전하고 입증 가능한 예는 어디에 있습니까? 거의 항상 잘못된 'feof'를 사용하는 것을 피하는 방법입니다. –

+0

으흠, 버전에 따라 여러 장의 인쇄물이 계속 나타납니다. 분명히 우리가이 데이터에 접근하는 방식에 문제가 있습니다. 하나의 레코드 만 있고 많은 레코드를 인쇄하고 있습니다. 읽는 바이트이기 때문에 이것이 가능합니까? 이 예제는 내가 구할 수있는만큼 작습니다. 이 바이너리 때문에 업로드 할 수없는 파일 –

1

더 많은 보호를 사용하십시오. 함수의 결과를 테스트하십시오. 영업 이익의 코드가 잘못 일치 printf 지정을 가지고 있기 때문에

FILE *p; 
struct myStruct x; 
p=fopen("myfile","rb"); 
assert(p); // Insure file opened 

while(1) { 
    size_t n = fread(&x, sizeof(x), 1, p); 
    // feof() is insufficient, 
    // fread() can fail due to input errors too and not set end-of-file condition 
    // if(feof(p)!=0) 
    if (n == 0) { 
    break; 
    } 
    // printf("\n\nID:%ld",x.ID); 
    printf("\n\nID:%d", x.ID); // Use matching specifier 
    fflush(stdout); // Insure output occurs promptly 
} 
fclose(p); 
return 0; 

, 그것은 하나의 경고가 완전히 활성화되지 않거나 영업 이익은 약한 컴파일러를 사용하고 있음을 나타냅니다. 시간을 절약하기위한 수정 제안

+0

안녕하세요, 하나의 가치. 즉, 구조체의 ID 부분을 읽지 않고 전체 구조체를 읽습니다. ID 부분 만 어떻게 만들 수 있습니까? –

+0

@Ke. "다른 말로 표현하면, 구조체의 ID 부분을 읽지 않습니다."는 "구조체 전체"와 모순됩니다. 코드는'ID '필드를 읽지 않고'struct'중에 읽을 수 없습니다. 나는 진실 된 코드를 의심하고 여기에 게시 한 내용이 다릅니다. 2 아이디어 :'fread (& x, sizeof (x), 1, p)'의'x'는 실제로 포인터이거나 읽는 파일이 생각보다 훨씬 큽니다. 파일 크기는 얼마입니까? – chux

관련 문제