从C中的不同文本文件创建值数组

时间:2014-10-02 13:23:11

标签: c arrays file-io

我在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)。

如果有任何想法/意见/建议,我很乐意听到。

感谢。

3 个答案:

答案 0 :(得分: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;
  }
}

答案 1 :(得分: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
}

或者,您的主程序可以迭代不同文件的值并调用函数,其状态模拟上述生成器处理值,最后使用处理函数的状态得到结果。

答案 2 :(得分:0)

尝试了一种稍微不同的方法,它的工作非常好。

每次我想要做的事情都不是从不同的文件中读取,我将每个文件的全部内容读入一个二维数组range_phase_data [sample_number] [pulse_number],然后访问数组的不同部分,具体取决于哪个我目前正在研究范围bin。

这是一段摘录:

#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
}

这减轻了动态分配文件指针的需要,而只是一次打开一个文件并将数据写入矩阵中的相应列。

干杯。