为什么 fprintf 在我的代码中没有按预期工作?

问题描述 投票:0回答:1

我有一个函数可以计算一些估计并将其打印到文件中。该程序在多个线程中调用,以针对不同的初始条件进行计算。每个线程创建单独的文件来写入值,因此不涉及文件冲突。这些值以科学记数法打印。我的问题是,在打印时,即使大多数值都正确打印,但有些(一两个)打印时缺少指数部分中的“e”,有一些 -ve 符号,或者通常会破坏格式。虽然这看起来并不重要,但它破坏了管道的其余部分,因为使用这些文件作为输入的程序无法正确解析它。下面给出了准系统代码。调用该函数的循环。

调用函数的循环。

for (int i = 0; i < 12; i++) {
        void* args[2] = {clock_pairs[i], Q_matrices[i]};
        pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args);
        printf("thread no %d ran \n",i);
        
    }

    for (int i = 0; i < 12; i++) {
        pthread_join(K_threads[i], NULL);
    }

这会将初始条件传递给一个函数,该函数组合参数并传递给计算值的函数。

void Calculate_Kalman(const char *filename, const char *filename1, double** processNoise)
{
    char kalman_filename[256];
    sprintf(kalman_filename, "K_%s_%s", filename, filename1);
    FILE *kalman_file = fopen(kalman_filename, "w");
        if (!kalman_file)
        {
            perror("Error opening file for writing");
            exit(EXIT_FAILURE);
        }
    char Error_filename[256];
    sprintf(Error_filename, "E_%s_%s", filename, filename1);
    FILE *E_file = fopen(Error_filename, "w");
        if (!E_file)
        {
            perror("Error opening file for writing");
            exit(EXIT_FAILURE);
        }
    
    for (int i = 0; i < SampleSize; i++)
    {

      
        kf.z = diff[i] + normalRandom(0,pow(measurementNoise,0.5));
        
        Kalman(&kf);  // Kalman function call.

        // Print the current state estimate

        fprintf(kalman_file, "%e, %e\n", gsl_matrix_get(kf.x, 0, 0), gsl_matrix_get(kf.x, 1, 0));
        fprintf(E_file, "%e,%e\n", gsl_matrix_get(kf.S, 0, 0), gsl_matrix_get(kf.S, 1, 0));

        // Add kf.S values to the dynamic matrix

        double row[NUM_VARS] = {gsl_matrix_get(kf.S, 0, 0), gsl_matrix_get(kf.S, 1, 0)};
        addRow(&matrix, row);

       
    }
    fclose(kalman_file);}

我删除了初始化系统的代码,因为它与问题无关。卡尔曼函数接收结构体 {kf} 并更新其中的值。循环中的 fprintf 命令应该将行打印到文件中。 kf 结构体定义如下

typedef struct
{
    gsl_matrix *x;    // State estimate (3x1 matrix)
    gsl_matrix *P;    // Error covariance (3x3 matrix)
    gsl_matrix *Q;    // Process noise covariance (3x3 matrix)
    double R;         // Measurement noise covariance (scalar)
    gsl_matrix *K;    // Kalman gain (3x1 matrix)
    gsl_matrix *Phi;  // State transition matrix (3x3 matrix)
    gsl_matrix *S;    // Noise vector (3x1 matrix)
    gsl_matrix *H;
    double z;
} KalmanFilter;

我尝试使用不同的格式样式(le而不是e),但它没有改变任何东西。事实上,这些错误在完全随机的文件中完全随机地出现也无济于事。

正常输出是这样的

-3.257449e-15, -1.437916e-18
8.742356e-11, 5.662028e-14
-1.929949e-10, -1.779626e-13
1.927338e-10, 2.305067e-13
-8.744399e-11, -1.284666e-13
........................
........................

但是一些不好的输出值看起来像这样

-3.0.049398e-13
1.-12
- -1.922051e-13

我在网上搜索,但找不到任何人提到类似的问题,我希望有人能对此有所启发。

c printf pthreads
1个回答
0
投票

您需要刷新有关变量的范围和生命周期的知识。

for (int i = 0; i < 12; i++) {
        void* args[2] = {clock_pairs[i], Q_matrices[i]};
        pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args);
        printf("thread no %d ran \n",i);
        
    }

在此代码中,在任何给定时间都只有 1 个数组

args
,并且在离开循环后,该变量根本不再有效。 这意味着,如果当您仍在循环中时执行其中一个线程(不能保证),它只会看到最后存储的内容。 如果线程在循环已经离开后执行,则内存不再有效并且读取内容会导致未定义的行为。

您必须使用静态内存。定义具有静态生存期的变量或使用动态内存分配:

void* args[12][2];
for (int i = 0; i < 12; i++) {
        args[i][0] = clock_pairs[i];
        args[i][1] = Q_matrices[i];
        pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args[i]);
        printf("thread no %d ran \n",i);
    }
© www.soinside.com 2019 - 2024. All rights reserved.