2014-07-05 2 views
0

에서 동적 배열과 gsl_vectors와 구조체를 읽어 바이너리 파일에 bar를 쓰고 다시 읽으려면 ... 어떻게하면됩니까?쓰기와 나는 비슷한 구조를 가지고 C

감사합니다.

는 편집 :

더 구체적으로, 나는 작동하지 않았다

fwrite(&bar,sizeof(*bar),1,file) 

하지만 sizeof(*bar)으로 노력하고 Google 검색에서 나는 sizeof 동적으로 구조의이 종류에서 작동하지 않는 것을 발견 내부 배열.

막대의 크기를 얻을 수있는 방법이 있습니까?

그렇지 않은 경우 각 요소에 fwrite을 배치해야하지만이 경우 동적 배열이 포함 된 다른 구조이기 때문에이 경우 gsl_vector 크기를 얻는 방법을 알지 못합니다.

+0

어를 ...'write' 그것을 (바이너리) 파일에 저장하고 다시 읽습니다. ... ... 그리고 Google이 말하지 않았습니까? – mafso

+0

아, 그리고 진지한 의견 : 엔디안을 찾으십시오. – mafso

+0

나는 인터넷 검색을 시도했지만 혼란스러운 것을 발견했습니다. 나는 C 프로그래머가 아니기 때문에 Google 결과에 대한 내 자신의 이해를 신뢰하기 전에 두 번 확인하고 싶습니다. – alexis

답변

0

sizeof(*bar)이 정확합니다. &bar이 잘못되었습니다. bar은 포인터이므로 주소 연산자를 사용하면 안됩니다.

또한 struct를 작성하려고 시도했지만 동적으로 할당 된 배열 데이터를 작성하지 않았습니다. 사실, 데이터를 다시 읽을 때 주소가 유효하지 않으므로 구조체를 작성하는 것은 의미가 없습니다. 크기 (mn)와 배열 데이터를 써야합니다. 다시 읽을 때 malloc/calloc 구조체와 배열 공간을 다시 필요로합니다.

다음은 실행 가능한 예입니다. gsl_vectordouble으로 바꾸어 다른 사람이 쉽게 실행할 수 있도록했습니다.

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

typedef struct { 
    int m, n; 
    int *am; 
    double *bn; 
} Foo; 

void foo_write(Foo *f, FILE *file) { 
    fwrite(&(f->m), sizeof(f->m), 1, file); 
    fwrite(&(f->n), sizeof(f->n), 1, file); 
    fwrite(f->am, sizeof(*(f->am)), f->m, file); 
    fwrite(f->bn, sizeof(*(f->bn)), f->n, file); 
} 

Foo *foo_read(FILE *file) { 
    Foo *f = malloc(sizeof(*f)); 
    fread(&(f->m), sizeof(f->m), 1, file); 
    fread(&(f->n), sizeof(f->n), 1, file); 
    f->am = malloc(f->m * sizeof(*(f->am))); 
    f->bn = malloc(f->n * sizeof(*(f->bn))); 
    fread(f->am, sizeof(*(f->am)), f->m, file); 
    fread(f->bn, sizeof(*(f->bn)), f->n, file); 
    return f; 
} 

Foo *foo_alloc(int m, int n) { 
    Foo *f = malloc(sizeof(*f)); 
    f->m = m; 
    f->n = n; 
    f->am = calloc(f->m, sizeof(*(f->am))); 
    f->bn = calloc(f->n, sizeof(*(f->bn))); 
    return f; 
} 

void foo_print(Foo *f) { 
    int i; 
    printf("%d, %d\n", f->m, f->n); 
    for (i = 0; i < f->m; ++i) 
     printf("%d ", f->am[i]); 
    putchar('\n'); 
    for (i = 0; i < f->n; ++i) 
     printf("%.1f ", f->bn[i]); 
} 

void foo_free(Foo *f) { 
    free(f->am); 
    free(f->bn); 
    free(f); 
} 

int main() { 
    FILE *file; 
    Foo *bar; 
    int i; 

    bar = foo_alloc(5, 10); 
    for (i = 0; i < bar->m; ++i) 
     bar->am[i] = i; 
    for (i = 0; i < bar->n; ++i) 
     bar->bn[i] = i; 


    file = fopen("foo.bin", "wb"); 
    foo_write(bar, file); 
    fclose(file); 

    foo_free(bar); 

    file = fopen("foo.bin", "rb"); 
    bar = foo_read(file); 
    fclose(file); 

    foo_print(bar); 

    return 0; 
} 
당신은 쓰기와 같은 gsl_vector의 (벡터들이 데이터 블록을 공유하지 않는, 즉, 독립적 인 가정) 읽을 수 있습니다

:

void foo_write(Foo *f, FILE *file) { 
    size_t i; 
    fwrite(&(f->m), sizeof(f->m), 1, file); 
    fwrite(&(f->n), sizeof(f->n), 1, file); 
    fwrite(f->am, sizeof(*(f->am)), f->m, file); 
    for (i = 0; i < f->n; ++i) 
     gsl_vector_fwrite(file, &(f->bn[i])); 
} 

Foo *foo_read(FILE *file) { 
    size_t i; 
    Foo *f = malloc(sizeof(*f)); 
    fread(&(f->m), sizeof(f->m), 1, file); 
    fread(&(f->n), sizeof(f->n), 1, file); 
    f->am = malloc(f->m * sizeof(*(f->am))); 
    f->bn = malloc(f->n * sizeof(*(f->bn))); 
    fread(f->am, sizeof(*(f->am)), f->m, file); 
    for (i = 0; i < f->n; ++i) 
     gsl_vector_fread(file, &(f->bn[i])); 
    return f; 
} 
+0

대단히 고마워요! 좋은 답변, 예를 들어 다른 질문에 대한 답변도 있습니다. 나는 gsl_vector로 당신의 예제를 시험해 보았고 잘 작동했다. 그러나 gsl_vector 내부에는 다른 동적 구조가 있습니다. foo_read에서와 같이 gsl_vector bn을 읽어야합니까? "fread (f-> bn, sizeof (* (f-> bn)), f-> n, file)로 성공한 이유는 무엇입니까? – alexis

+1

@alexis'gsl_vector's를 보면, 일들은 확실히 더 복잡합니다. 모든 벡터가 독립적 인 경우 (각각 자체 데이터 블록을 소유하고있는 경우),'gsl_vector_fwrite'와'gsl_vector_fread'를 사용할 수 있습니다 (위의 편집 참조). 데이터가있는 메모리가 아직 존재하지 않았기 때문에 간단한 fwrite가 작동했을 수도 있습니다. 데이터를 저장하는 프로그램 하나와 그것을 읽는 다른 프로그램을 작성하면 확실히 작동하지 않을 것입니다. – ooga

+0

감사합니다! 그리고 특히 마지막 편집과 코멘트에 감사드립니다. 정말 도움이되었습니다. – alexis