2013-01-22 33 views
0

我有一個ASCII文件,其中存儲了矢量的條目。我不知道文件的長度(行數),也不知道它的大小,因爲它可能從幾行到幾萬不等。我需要一種有效的方式來讀取存儲在該文件中的數據並將它們加載到float *變量中。代碼應該在C.如何將文件中的數據加載到C中的float *

我的問題是如何爲我需要創建的向量分配內存,因爲我事先不知道它的大小?你能舉個例子嗎?

最後,你認爲最適合這種功能的原型是什麼?應該是這樣的:

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

更新1:雖然做了一些初步的測試,我寫了下面的代碼:

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返回數組。取而代之的是,當我把它從我的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 float矩陣,用* matrix =(float *)malloc ...分配內存,並相應地填充矩陣。 –

+0

@someguy非常感謝!的確,你是對的!所以,我的方法的原型畢竟應該是'load_data(const char * filename,float ** data,int * vector_size);',對吧? –

回答

1

fgets是你從文件中讀取數據的朋友(如果我假設每一位數據位於新行都是正確的)。閱讀1中的每一行,並在您閱讀的文字上使用strtof。閱讀文本和轉換爲浮動本質上是一個緩慢的過程,所以我認爲上述是非常好的。

至於你的第二個問題,有幾種方法可以做到這一點。你可以傳入一個float **,並在函數內部建立malloc。雖然這有一個缺點,那就是你需要將它釋放到不明顯的功能之外。我能想到的唯一方法是掃描文件並計算新行的數量,然後爲其分配數組長度。

很難說是否執行malloc和一堆reallocs會比掃描通過計算行數更有效率,但可能值得嘗試兩種方法(兩者都不是特別困難),並且看看哪一個對你來說更快。

+3

使用'strtod'而不是'atof'。 –

+0

@WilliamPursell'atof'和'strtod'之間的本質區別是什麼? –

+1

使用'atof',如果值不能表示,行爲是不確定的。 –

相關問題