2013-01-22 6 views
0

벡터 항목이 저장된 ASCII 파일이 있습니다. 필자는 파일의 길이 (행 수)를 알지 못하며 몇 줄에서 수만 줄까지 다양 할 수 있기 때문에 그 크기에 대한 추정치를 가지고 있지 않습니다. 해당 파일에 저장된 데이터를 읽고 float * 변수에로드하는 효율적인 방법이 필요합니다. 코드는 C로 작성되어야합니다.파일에서 float *로 데이터를로드하는 방법

제 질문은 미리 크기를 모르는 상태에서 작성해야하는 벡터에 대해 메모리를 할당하는 방법입니다. 예를 들어 주시겠습니까?

마지막으로 그러한 기능에 가장 적합한 프로토 타입은 무엇입니까? 다음과 같은 형식이어야합니다 :

load_data(const char* filename, float* data, int* vector_size); 

?

void create_random_matrix(float* matrix, const int nrows) { 
    matrix = (float *) malloc(sizeof (float) * nrows); 
    short i; 
    for (i = 0; i < nrows; i++) { 
     matrix[i] = 7.0f; 
    } 
} 

7.0f와 같은 모든 요소 배열을 반환해야합니다

업데이트 1 : 몇 가지 초기 테스트를하는 동안

, 나는 다음과 같은 코드를 썼습니다. 대신, 내 main.c의에서 호출 할 때 :

float *a; 
create_random_matrix(a, 10);  
printf("%f",a[0]); 

0.0f로를 인쇄합니다. 그게 어떻게 가능하니?!

업데이트 2. 당신의 도움을 위해 그것을 아니 었, 다음 (작업) 코드가 기록되지 않았을 :

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 

#define LINE_SIZE 10 
#define ALLOCATION_CHUNK 50 

int load_vector_data(const char* filename, float** vector, int* length) { 
    *vector = malloc(sizeof (float) * ALLOCATION_CHUNK); 
    int allocated_rows = ALLOCATION_CHUNK; 
    u_short i = 0; 
    FILE* fr = fopen(filename, "r"); 
    if (fr == NULL) { 
     exit(FILE_NOT_FOUND); 
    } 
    char line[LINE_SIZE]; 
    while (fgets(line, LINE_SIZE, fr) != NULL) { 
     if (i >= allocated_rows){   
      allocated_rows += ALLOCATION_CHUNK; 
      *vector = realloc(*vector, sizeof (float) * allocated_rows); 
     } 
     strip_newline(&line, LINE_SIZE); 
     (*vector)[i] = strtod(line, (char **) NULL); 
     i++; 
    } 
    *length = i; 
    *vector = realloc(*vector, sizeof (float) * i); 
    fclose(fr); 
} 

void strip_newline(char *str, int size) { 
    u_short i; 
    for (i = 0; i < size; ++i) { 
     if (str[i] == '\n') { 
      str[i] = '\0'; 
      return; 
     } 
    } 
} 

내가 8000 선이 파일을 시도하고 작동하는 것 같군 그냥 괜찮아! 제발, 자유롭게 논평 해주세요.

+3

파일을 고정 크기로 읽어 들이고, 각 부분을 결과 버퍼에 복사합니다.이 때마다 'realloc'에 의해 크기가 조정됩니다. –

+1

@Pantelis Sopasakis : (Update1에서) 함수의 인수에'float ** matrix'를 전달하고'* matrix = (float *) malloc ... '으로 메모리를 할당하고 이에 따라 행렬을 채 웁니다. –

+0

@someguy 정말 고마워! 사실, 당신 말이 맞아요! 그래서, 내 메소드의 프로토 타입은 모두'load_data (const char * filename, float ** data, int * vector_size); '이어야합니다. –

답변

1

fgets 파일에서 데이터를 읽는 친구가 될 수 있습니다 (데이터의 각 비트가 줄 바꿈이라고 가정 할 경우). 읽는 텍스트에 1 행 1 행을 읽고 strtof을 사용하십시오. 텍스트를 읽고 플로트로 변환하는 것은 본질적으로 느린 과정이므로 위의 내용이 완벽하게 충분하다고 생각합니다.

두 번째 질문에 대해서는 두 가지 방법이 있습니다. float **을 전달하여 함수 내부에 malloc을 만들 수 있습니다. 이것은 분명히 분명하지 않은 함수 밖에서 그것을 해제해야하는 단점이 있지만. 내가 생각할 수있는 유일한 다른 방법은 파일을 스캔하여 새 줄 수를 계산 한 다음 배열 길이를 미리 할당하는 것입니다.

malloc과 realloc을 수행하는 것이 줄 수를 계산하는 것보다 효율적인지 여부는 말하기 어렵지만 두 방법 모두 시도하지 않는 것이 좋습니다 (특히 어렵지 않음). 당신을 위해 더 빠릅니다.

+3

'atof' 대신'strtod'를 사용하십시오. –

+0

@WilliamPursell'atof'와'strtod'의 근본적인 차이점은 무엇입니까? –

+1

'atof'를 사용하면 값을 표현할 수 없으면 동작이 정의되지 않습니다. –

관련 문제