2014-10-02 71 views
0

我在C上使用64位Ubuntu 14.04。從C中的不同文本文件創建一個數組數組C

我有許多.txt文件,每個文件都包含浮點值行(每行1個值)。這些線表示一個複雜樣本的一部分,並且它們以真實(a1)\ n imag(a1)\ n real(a2)\ n imag(a2)的形式存儲,如果有意義的話。

在一個特定的場景中有4個文本文件,每個文件包含32768個樣本(因此65536個值),但是我需要使最終版本動態以容納多達32個文件(儘管每個文件的最大樣本數不會超過32768) 。儘管如此,我只會讀取前19800個樣本(取決於其他事物),因爲整個信號包含在這39600個點(19800個樣本)中。

一個常見的抽象是表示文件/樣本作爲一個矩陣,其中列表示的返回信號和行以採樣時刻表示各信號的值,直到最大持續時間。

我想要做的是從每個返回信號中取出第一個樣本,並將其移入雙精度浮點值的數組中,以完成一些工作,然後轉到第二個樣本以獲取每個信號(其中將覆蓋前面的數組),並對它們做一些處理,等等,直到最後一行樣本被處理完畢。

是否有一種方法可以動態地爲每個信號打開文件(取決於在該特定實例中使用的脈衝數),將每個文件的第一個樣本讀入緩衝區並將其發送到被處理。在下一次迭代中,文件指針將全部與第二個樣本對齊,然後將它們移入數組並重新發布,直到達到所需數量的樣本(我們假設的情況下爲19800)。

我可以使用的fscanf讀取樣本文件就好了:

rx_length = 19800; 
int x; 
float buf; 

double *range_samples = calloc(num_pulses, 2 * sizeof(range_samples)); 

for (i=0; i < 2 * rx_length; i++){ 
    x = fscanf(pulse_file, "%f", &buf); 
    *(range_samples) = buf; 
} 

所有需要發生(在我心中)是我需要循環兩種樣品#和脈衝#(按順序) ,所以當一個脈衝結束,將上移到下一組樣本的下一個脈衝,等等。我不知道該如何做的是以某種方式爲所有返回信號文件聲明文件指針,當它們的數量可以在不同的調用之間變化時(例如,對於4個脈衝做整個事情,並且在下一次調用時它可以是16或64)。

如果有任何想法/意見/建議,我很願意聽到他們的聲音。

謝謝。

+0

在程序開始處已知文件列表,還是在程序運行時創建新文件時進行實時處理? – 2014-10-02 14:07:24

+0

是的,文件是rx_1_out.txt,其中1代表脈衝數。 – user2742907 2014-10-02 17:15:51

回答

1

我會讓你的代碼發佈一個函數,它的文件名的數組作爲參數:

void doPulse(const char **file_names, const int size) 
{ 
    FILE *file = 0; 

    // declare your other variables 

    for (int i = 0; i < size; ++i) 
    { 
    file = fopen(file_names[i]); 

    // make sure file is open 
    // do the work on that file 

    fclose(file); 
    file = 0; 
    } 
} 
0

你需要的是一臺發電機。這將是C++相當容易,但是當你標記C,我能想象一個功能,將用戶自定義結構作爲參數(對象的狀態)。這可能是這樣的(僞代碼):

struct GtorState { 
    char *files[]; 
    int filesIndex; 
    FILE *currentFile; 
}; 

void gtorInit(GtorState *state, char **files) { 
    // loads the array of file into state, set index to 0, and open first file 
} 

int nextValue(GtorState *state, double *real, double *imag) { 
    // read 2 values from currentFile and affect them to real and imag 
    // if eof, close currentFile and open files[++currentIndex] 
    // if real and imag were found returns 0, else 1 if eof on last file, 2 if error 
} 

然後你的主程序可以包含:

GtorState state; 
// initialize the list of files to process 
gtorInit(&state, files); 

double real, imag); 
int cr; 
while (0 == (cr = nextValue(&state, &real, &imag)) { 
    // process (real, imag) 
} 
if (cr == 2) { 
    // process (at least display) error 
} 

或者,你的主程序可以重複的不同文件的值,並調用函數狀態上述生成器的模擬處理值,最後使用處理函數的狀態來獲得結果。

0

嘗試了一個稍微不同的方法,它工作得很好。

每次我想要做某件事時,我都會將每個文件的全部內容讀取到二維數組range_phase_data [sample_number] [pulse_number]中,然後訪問數組的不同部分,取決於我目前正在研究的範圍箱。

下面是摘錄:

#define REAL(z,i) ((z)[2*(i)]) 
#define IMAG(z,i) ((z)[2*(i)+1]) 

for (i=0; i<rx_length; i++){ 
    printf("\t[%s] Range bin %i. Samples %i to %i.\n", __FUNCTION__, i, 2*i, 2*i+1); 
    for (j=0; j<num_pulses; j++){ 
     REAL(fft_buf, j) = range_phase_data[2*i][j]; 
     IMAG(fft_buf, j) = range_phase_data[2*i+1][j]; 
    } 
    printf("\t[%s] Range bin %i done, ready to FFT.\n", __FUNCTION__, i); 

    // do stuff with the data 
} 

這減輕了需要動態分配文件指針和代替剛剛打開一個文件的時間和將數據寫入到矩陣中相應的列。

乾杯。