2014-10-02 3 views
0

Я работаю в C на 64-разрядном Ubuntu 14.04.Создайте массив значений из разных текстовых файлов в 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

Является ли список файлов, известных в начале программы, или это обработка в реальном времени с созданием новых файлов во время работы программы? –

+0

Да, файлы rx_1_out.txt, где 1 - номер импульса. – user2742907

ответ

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

Пробовал немного другой подход, и он работает очень хорошо.

Вместо чтения из разных файлов каждый раз, когда я хочу что-то сделать, я читаю все содержимое каждого файла в 2D-массив 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 
} 

Это устраняет необходимость динамически выделяемые указатели файлов и вместо просто открывает файлы по одному за раз, и записывает данные в соответствующий столбец в матрице.

Cheers.