使用来自一维结构阵列的信息填充二维结构阵列

时间:2016-03-19 22:36:18

标签: c arrays multidimensional-array struct

我写了一个函数,成功读取每个记录使用以下格式的CSV文件:

name_of_class,name_of_class_member,double_associated_with_class,double_associated_with_class_member,another_double_associated_with_class_member

我的函数读取CSV文件并创建一维结构数组,其中每个记录对应于一维结构数组中的元素。

我的问题是:如何将每条记录的信息复制到二维结构数组中,索引为data[class][member_of_class]而不是data[record]

这很棘手,因为不同的班级有不同数量的成员。我初始化了一个维度为classes * max_num_members的二维数组,并将二维数组的值设置为零(或者,在char数组的情况下,我使用的空格稍后会被其他字符写入)。因此,显然,2D阵列中将存在许多值(对于char数组的双精度或空白空间等于零),这些值未通过从1D阵列复制而被更改。我可以使用哨兵在我的主算法中跳过这些。

目标是在代码中稍后使用我的嵌套for循环来循环遍历类的成员作为嵌套循环并将类作为外部循环循环。代码的那部分已经完成并正常工作,但是我需要将数据读入算法使用的结构数组中。有人知道怎么做吗?

另一种方法是将我的记录从csv文件读取到2D数组中,但这实际上只是将问题从一个位置转移到另一个位置。类名不得超过十个字符,成员名不得超过十三个字符。

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

struct csv
{
    char class_name[12];
    char member[18];
    double class_value;
    double member_value1;
    double member_value2;
    double calc_output1;  // Program I'm writing adds values here
    double calc_output2; // And here
};

void readFile(char *csvFile, struct csv *csv_rec)
{
    /* code for reading file here - this works as planned.
       Reads csv file and makes 1D array of structs with num_records
       elements */
    FILE *dataFile = NULL;
//  size_t idx_i = 0;       // struct array index i (increments after every record -> resets to zero when a new ligand is found)
//  size_t idx_j = 0;       // struct array index j (only increments when a new ligand is found)
    size_t idx = 0;         // okay - this lie_read struct array will be one-dimensional - one index per record
    size_t fldidx = 0;      // struct field index
    char fileLine[255] = {0};
    char *p = NULL;         // pointer to line

    dataFile = fopen(myFile, "r");

    // Open the file set by the command line and read it into the file object
    dataFile = fopen(myFile, "r");
    if (dataFile == NULL){
        perror("Error opening data file.\n");
        exit(EXIT_FAILURE);     // Exit program if data file cannot be read by runtime service
    }

    while ((fgets (fileLine, 254, dataFile)) != NULL){
        fldidx = 0;     // reset field index for each line
        // Use strtok to separate each line into tokens on ','
        for (p = strtok(fileLine, ","); p != NULL; p = strtok(NULL, ",")){
            // Use fldidx to separate data into struct
            switch (fldidx){

                case 0:
                    strncpy(lie_rec[idx].class_name, p, strlen(p));
                    break;

                case 1:
                    strncpy(lie_rec[idx].member, p, strlen(p));
                    break;

                case 2:
                    lie_rec[idx].class_value = atof(p);
                    break;

                case 3:
                    lie_rec[idx].member_value1 = atof(p);
                    break;

                case 4:
                    lie_rec[idx].member_value2 = atof(p);
                    break;
            }
            // Increment field index
            fldidx++;
        }
        // Increment record index
        idx++;
    }
    // Close dataFile object
    fclose(dataFile);
}

int main(int argc, char *argv[])
{
    int num_records = 75; // Later a function will count these
    struct csv csv_data[m_members][n_classes]; // Declare 2D array 
    struct csv csv_read[num_records]; // 1D array of structs
    int i; // index for printing out 2D array
    int j; // index for printing out 2D array
    int members; // members counter for algorithm I wrote
    int classes; // classes counter
    int records; // index of records
    int m_members = 25; // Bigger than it needs to be for any file
    int n_classes = 25; // Bigger than needs to be for any file

    // Initialize csv_data 2D array:
    for (i = 0; i < m; i += 1){
        for (j = 0; j < n; j += 1){
            strcpy(csv_data[i][j].class_name, "          ");
            strcpy(csv_data[i][j].member, "                ");
            csv_data[i][j].class_value = 0.0;
            csv_data[i][j].member_value1 = 0.0;
            csv_data[i][j].member_value2 = 0.0;
            csv_data[i][j].calc_output1 = 0.0;
            csv_data[i][j].calc_output2 = 0.0;
        }
   }
// Initialize csv_read struct array
    for (records = 0; records < num_records; records += 1){
        strcpy(csv_read[records].class_name, "          ");
        strcpy(csv_read[records].member, "                ");
        csv_read[records].class_value = 0.0;
        csv_read[records].member_value1 = 0.0;
        csv_read[records].member_value2 = 0.0;
        csv_read[records].calc_output1 = 0.0;
        csv_read[records].calc_output2 = 0.0;
    }

    if (argc != 2){
        printf("Usage: ./optimization datafile.csv\n");
        return 1;       
    }

    readFile (argv[1], csv_read);

    // Here is what I have so far. It doesn't work:
    // First, set member and class indices to zero
    members = 0;
    classes = 0;

   // Next, copy values held in first record to 0,0 index of 2D array
       strcpy(csv_data[classes][members].class_name, csv_read[0].class_name);
       strcpy(csv_data[classes][members].member, csv_read[0].member);
       csv_data[classes][members].class_value = csv_read[0].class_value;
       csv_data[classes][members].member_value1 = csv_read[0].member_value1;
       csv_data[classes][members].member_value2 = csv_read[0].member_value2;

       // This is the part I'm not doing correctly:
      for (records = 1; records < num_records; records += 1){
          if (csv_read[records].class_name == csv_read[records -1].class_name){
              members += 1;
              strcpy(csv_data[classes][members].class_name, csv_read[records].class_name);
              strcpy(csv_data[classes][members].member, csv_read[records].member);
              csv_data[classes][members].class_value = csv_read[records].class_value;
              csv_data[classes][members].member_value1 = csv_read[records].member_value1;
              csv_data[classes][members].member_value2 = csv_read[records].member_value2;
          }
          else{
              members = 0;
              classes += 1;
              strcpy(csv_data[classes][members].class_name, csv_read[records].class_name);
              strcpy(csv_data[classes][members].member, csv_read[records].member);
              csv_data[classes][members].class_value = csv_read[records].class_value;
              csv_data[classes][members].member_value1 = csv_read[records].member_value1;
              csv_data[classes][members].member_value2 = csv_read[records].member_value2;
          }
      }
  for (i = 0; i < n_classes; i += 1){
      for (j = 0; j < m_members; j += 1){
            printf("Class: %s\tMember: %s\tClass val: %.2f\tMem val 1: %.2f\tMem val 2: %.2f\tClass index i: %d\tMember index j: %d\n", \
            csv_data[i][j].class_name, csv_data[i][j].member, csv_data[i][j].class_value, \
            csv_data[i][j].member_value1, csv_data[i][j].member_value2, i, j);

            }
        }
    return 0;
}

编辑:请考虑以下数据:

RTI-31,nma-10-325,-9.189617432,-1.695719104,-17.76402898
RTI-31,nma-04-176,-9.189617432,-0.708200772,-17.29511154
RTI-31,nma-04-176r,-9.189617432,-1.776907169,-18.88678457
RTI-31,md2-02-280,-9.189617432,-6.716602886,-17.30751521
RTI-31,nma-10-346,-9.189617432,-11.25116643,-15.84743342
RTI-31,nma-04-263,-9.189617432,-11.7115346,-15.04227866
RTI-31,nma-08-195,-9.189617432,-4.283013542,-14.8644087
RTI-31,nma-04-009,-9.189617432,-9.957288662,-15.3833286
RTI-32,nma-10-088,-8.122152987,3.400737344,-13.82064615
RTI-32,nma-04-394,-8.122152987,5.883495783,-19.00254755
RTI-32,nma-08-230,-8.122152987,0.413386417,-17.50831526
RTI-32,md2-01-186,-8.122152987,2.302141507,-18.42063173
RTI-32,md2-02-029,-8.122152987,-0.853363293,-19.87712031
RTI-32,md2-03-113,-8.122152987,-2.126838817,-17.89035308
RTI-32,md2-03-408,-8.122152987,-2.378811839,-19.10012534
RTI-32,nma-08-230r,-8.122152987,-3.518076683,-15.81202945
RTI-32,md2-02-440,-8.122152987,-1.188031285,-19.53715485
RTI-32,nma-10-450,-8.122152987,-8.146774789,-16.31970845
RTI-55,nma-10-001,-10.81805764,-5.533121698,-21.43344143
RTI-55,mod-15-206,-10.81805764,-7.885292487,-15.77724091
RTI-55,mod-15-315,-10.81805764,-8.856570799,-14.75351417
RTI-55,md2-02-326,-10.81805764,-5.707098223,-17.26686476
RTI-55,md2-02-385-2ns,-10.81805764,-4.121861538,-19.3591163
RTI-55,md2-02-385,-10.81805764,-4.947616016,-18.97695889
RTI-55,mod-20-399,-10.81805764,-10.22068836,-16.32632494
RTI-55,nma-04-221,-10.81805764,-10.71500752,-16.91671567
RTI-55,nma-10-386,-10.81805764,-1.85786946,-16.19619261
RTI-83,nma-10-442,-8.776665815,-2.051376338,-15.3196037
RTI-83,nma-07-088,-8.776665815,-0.539301859,-15.72769426
RTI-83,md2-02-373,-8.776665815,-1.906149626,-16.11155781
RTI-83,nma-08-131,-8.776665815,0.313343619,-19.40078361
RTI-83,nma-08-496,-8.776665815,1.261873671,-19.855084
RTI-83,nma-08-496r,-8.776665815,-3.209539767,-19.77852301
RTI-83,nma-10-083,-8.776665815,-1.389051189,-16.46193737
RTI-112,nma-04-356,-10.01552067,-7.703118545,-18.74684866
RTI-112,nma-12-269,-10.01552067,-2.041048837,-17.43378148
RTI-112,md2-02-251,-10.01552067,-4.164610755,-18.10792907
RTI-112,md2-03-020,-10.01552067,-5.530673965,-18.65868875
RTI-112,md2-03-112,-10.01552067,-4.616037982,-17.8977875
RTI-112,md2-05-001r,-10.01552067,10.61243604,-18.16726877
RTI-112,md2-02-424,-10.01552067,-6.748664848,-14.45256624
RTI-112,md2-04-136,-10.01552067,-1.418702078,-17.52802883
RTI-112,md2-04-432,-10.01552067,5.711770139,-19.62800474
RTI-112,nma-12-269r,-10.01552067,6.293115989,-21.18562611
RTI-112,md2-02-366,-10.01552067,-7.398526621,-15.27947209
RTI-112,nma-10-060,-10.01552067,0.203776856,-16.07514793
RTI-112,nma-10-009,-10.01552067,-8.496101809,-15.4687674
RTI-121,nma-04-080,-8.23077347,-13.26577889,-19.92387515
RTI-121,md2-02-121,-8.23077347,-6.908416206,-21.19849859
RTI-121,md2-01-352,-8.23077347,-3.905511834,-20.05735835
RTI-121,md2-02-008,-8.23077347,-7.466873501,-20.41795091
RTI-121,md2-03-176,-8.23077347,-10.52147618,-20.31241965
RTI-121,md2-03-414,-8.23077347,-8.16490714,-21.51488985
RTI-121,md2-02-161,-8.23077347,-10.90084,-18.37585263
RTI-121,md2-02-385,-8.23077347,0.522082608,-16.89841543
RTI-121,nma-09-401,-8.23077347,-9.558324522,-18.10430351
RTI-121,nma-10-395,-8.23077347,-2.742911754,-17.7883527
RTI-311,nma-10-120,-9.189617432,-13.42937635,-14.86997145
RTI-311,md2-02-009,-9.189617432,-6.894222241,-15.63990294
RTI-311,mod-22-300,-9.189617432,-12.76870958,-16.02814399
CPT,mod-08-107,-7.817821853,4.236459518,-19.75666039
CPT,md2-02-359,-7.817821853,-3.738716789,-16.07115237
CPT,mod-22-290,-7.817821853,6.6227657,-16.84444512
CPT,nma-10-155,-7.817821853,-1.792262141,-13.302963
CPT,nma-10-405,-7.817821853,-2.6011009,-15.99324198
CFT,mod-08-220,-8.451839575,-3.405297094,-18.91334067
CFT,md2-02-111,-8.451839575,-6.573973681,-14.8400486

产生这些奇怪的结果(注意最后一个类 - CFT - 尚未打印):

]]RTI-31,nma-10-325,-9.189617432,-1.695719104,-17.76402898
]]RTI-31,nma-04-176,-9.189617432,-0.708200772,-17.29511154
]]RTI-31,nma-04-176r,-9.189617432,-1.776907169,-18.88678457
]]RTI-31,md2-02-280,-9.189617432,-6.716602886,-17.30751521
]]RTI-31,nma-10-346,-9.189617432,-11.25116643,-15.84743342
]]RTI-31,nma-04-263,-9.189617432,-11.7115346,-15.04227866
]]RTI-31,nma-08-195,-9.189617432,-4.283013542,-14.8644087
]]RTI-31,nma-04-009,-9.189617432,-9.957288662,-15.3833286
]]RTI-32,nma-10-088,-8.122152987,3.400737344,-13.82064615
]]RTI-32,nma-04-394,-8.122152987,5.883495783,-19.00254755
]]RTI-32,nma-08-230,-8.122152987,0.413386417,-17.50831526
]]RTI-32,md2-01-186,-8.122152987,2.302141507,-18.42063173
]]RTI-32,md2-02-029,-8.122152987,-0.853363293,-19.87712031
]]RTI-32,md2-03-113,-8.122152987,-2.126838817,-17.89035308
]]RTI-32,md2-03-408,-8.122152987,-2.378811839,-19.10012534
]]RTI-32,nma-08-230r,-8.122152987,-3.518076683,-15.81202945
]]RTI-32,md2-02-440,-8.122152987,-1.188031285,-19.53715485
]]RTI-32,nma-10-450,-8.122152987,-8.146774789,-16.31970845
]]RTI-55,nma-10-001,-10.81805764,-5.533121698,-21.43344143
]]RTI-55,mod-15-206,-10.81805764,-7.885292487,-15.77724091
]]RTI-55,mod-15-315,-10.81805764,-8.856570799,-14.75351417
]]RTI-55,md2-02-326,-10.81805764,-5.707098223,-17.26686476
]]RTI-55,md2-02-385-2ns,-10.81805764,-4.121861538,-19.3591163
]]RTI-55,md2-02-385,-10.81805764,-4.947616016,-18.97695889
]]RTI-55,mod-20-399,-10.81805764,-10.22068836,-16.32632494
]]RTI-55,nma-04-221,-10.81805764,-10.71500752,-16.91671567
]]RTI-55,nma-10-386,-10.81805764,-1.85786946,-16.19619261
]]RTI-83,nma-10-442,-8.776665815,-2.051376338,-15.3196037
]]RTI-83,nma-07-088,-8.776665815,-0.539301859,-15.72769426
]]RTI-83,md2-02-373,-8.776665815,-1.906149626,-16.11155781
]]RTI-83,nma-08-131,-8.776665815,0.313343619,-19.40078361
]]RTI-83,nma-08-496,-8.776665815,1.261873671,-19.855084
]]RTI-83,nma-08-496r,-8.776665815,-3.209539767,-19.77852301
]]RTI-83,nma-10-083,-8.776665815,-1.389051189,-16.46193737
]]RTI-112,nma-04-356,-10.01552067,-7.703118545,-18.74684866
]]RTI-112,nma-12-269,-10.01552067,-2.041048837,-17.43378148
]]RTI-112,md2-02-251,-10.01552067,-4.164610755,-18.10792907
]]RTI-112,md2-03-020,-10.01552067,-5.530673965,-18.65868875
]]RTI-112,md2-03-112,-10.01552067,-4.616037982,-17.8977875
]]RTI-112,md2-05-001r,-10.01552067,10.61243604,-18.16726877
]]RTI-112,md2-02-424,-10.01552067,-6.748664848,-14.45256624
]]RTI-112,md2-04-136,-10.01552067,-1.418702078,-17.52802883
]]RTI-112,md2-04-432,-10.01552067,5.711770139,-19.62800474
]]RTI-112,nma-12-269r,-10.01552067,6.293115989,-21.18562611
]]RTI-112,md2-02-366,-10.01552067,-7.398526621,-15.27947209
]]RTI-112,nma-10-060,-10.01552067,0.203776856,-16.07514793
]]RTI-112,nma-10-009,-10.01552067,-8.496101809,-15.4687674
]]RTI-121,nma-04-080,-8.23077347,-13.26577889,-19.92387515
]]RTI-121,md2-02-121,-8.23077347,-6.908416206,-21.19849859
]]RTI-121,md2-01-352,-8.23077347,-3.905511834,-20.05735835
]]RTI-121,md2-02-008,-8.23077347,-7.466873501,-20.41795091
]]RTI-121,md2-03-176,-8.23077347,-10.52147618,-20.31241965
]]RTI-121,md2-03-414,-8.23077347,-8.16490714,-21.51488985
]]RTI-121,md2-02-161,-8.23077347,-10.90084,-18.37585263
]]RTI-121,md2-02-385,-8.23077347,0.522082608,-16.89841543
]]RTI-121,nma-09-401,-8.23077347,-9.558324522,-18.10430351
]]RTI-121,nma-10-395,-8.23077347,-2.742911754,-17.7883527
]]RTI-311,nma-10-120,-9.189617432,-13.42937635,-14.86997145
]]RTI-311,md2-02-009,-9.189617432,-6.894222241,-15.63990294
]]RTI-311,mod-22-300,-9.189617432,-12.76870958,-16.02814399
]]CPT,mod-08-107,-7.817821853,4.236459518,-19.75666039
]]CPT,md2-02-359,-7.817821853,-3.738716789,-16.07115237
]]CPT,mod-22-290,-7.817821853,6.6227657,-16.84444512
]]CPT,nma-10-155,-7.817821853,-1.792262141,-13.302963
]]CPT,nma-10-405,-7.817821853,-2.6011009,-15.99324198
]]CFT,mod-08-220,-8.451839575,-3.405297094,-18.91334067
]]CFT,md2-02-111,-8.451839575,-6.573973681,-14.8400486
[0,1] - A
[0,2] - A
[0,3] - A
[0,4] - A
[0,5] - A
[0,6] - A
[0,7] - A
[1,0] - B
[1,1] - A
[1,2] - A
[1,3] - A
[1,4] - A
[1,5] - A
[1,6] - A
[1,7] - A
[1,8] - A
[1,9] - A
[2,0] - B
[2,1] - A
[2,2] - A
[2,3] - A
[2,4] - A
[2,5] - A
[2,6] - A
[2,7] - A
[2,8] - A
[3,0] - B
[3,1] - A
[3,2] - A
[3,3] - A
[3,4] - A
[3,5] - A
[3,6] - A
[4,0] - B
[4,1] - A
[4,2] - A
[4,3] - A
[4,4] - A
[4,5] - A
[4,6] - A
[4,7] - A
[4,8] - A
[4,9] - A
[4,10] - A
[4,11] - A
[4,12] - A
[5,0] - B
[5,1] - A
[5,2] - A
[5,3] - A
[5,4] - A
[5,5] - A
[5,6] - A
[5,7] - A
[5,8] - A
[5,9] - A
[6,0] - B
[6,1] - A
[6,2] - A
[7,0] - B
[7,1] - A
[7,2] - A
[7,3] - A
[7,4] - A
[8,0] - B
[8,1] - A
Class         Member                C-Value  M-Value 1  M-Value 2   Class  Member
RTI-31        nma-10-325              -9.19      -1.70     -17.76       0       0
RTI-31        nma-04-176              -9.19      -0.71     -17.30       0       1
RTI-31        nma-04-176r             -9.19      -1.78     -18.89       0       2
RTI-31        md2-02-280              -9.19      -6.72     -17.31       0       3
RTI-31        nma-10-346              -9.19     -11.25     -15.85       0       4
RTI-31        nma-04-263              -9.19     -11.71     -15.04       0       5
RTI-31        nma-08-195              -9.19      -4.28     -14.86       0       6
RTI-31        nma-04-009              -9.19      -9.96     -15.38       0       7
                                       0.00       0.00       0.00       0       8
                                       0.00       0.00       0.00       0       9
                                       0.00       0.00       0.00       0      10
                                       0.00       0.00       0.00       0      11
RTI-32        nma-10-088              -8.12       3.40     -13.82       1       0
RTI-32        nma-04-394              -8.12       5.88     -19.00       1       1
RTI-32        nma-08-230              -8.12       0.41     -17.51       1       2
RTI-32        md2-01-186              -8.12       2.30     -18.42       1       3
RTI-32        md2-02-029              -8.12      -0.85     -19.88       1       4
RTI-32        md2-03-113              -8.12      -2.13     -17.89       1       5
RTI-32        md2-03-408              -8.12      -2.38     -19.10       1       6
RTI-32        nma-08-230r             -8.12      -3.52     -15.81       1       7
RTI-32        md2-02-440              -8.12      -1.19     -19.54       1       8
RTI-32        nma-10-450              -8.12      -8.15     -16.32       1       9
                                       0.00       0.00       0.00       1      10
                                       0.00       0.00       0.00       1      11
RTI-55        nma-10-001             -10.82      -5.53     -21.43       2       0
RTI-55        mod-15-206             -10.82      -7.89     -15.78       2       1
RTI-55        mod-15-315             -10.82      -8.86     -14.75       2       2
RTI-55        md2-02-326             -10.82      -5.71     -17.27       2       3
RTI-55        md2-02-385-2ns         -10.82      -4.12     -19.36       2       4
RTI-55        md2-02-385             -10.82      -4.95     -18.98       2       5
RTI-55        mod-20-399             -10.82     -10.22     -16.33       2       6
RTI-55        nma-04-221             -10.82     -10.72     -16.92       2       7
RTI-55        nma-10-386             -10.82      -1.86     -16.20       2       8
                                       0.00       0.00       0.00       2       9
                                       0.00       0.00       0.00       2      10
                                       0.00       0.00       0.00       2      11
RTI-83        nma-10-442              -8.78      -2.05     -15.32       3       0
RTI-83        nma-07-088              -8.78      -0.54     -15.73       3       1
RTI-83        md2-02-373              -8.78      -1.91     -16.11       3       2
RTI-83        nma-08-131              -8.78       0.31     -19.40       3       3
RTI-83        nma-08-496              -8.78       1.26     -19.86       3       4
RTI-83        nma-08-496r             -8.78      -3.21     -19.78       3       5
RTI-83        nma-10-083              -8.78      -1.39     -16.46       3       6
                                       0.00       0.00       0.00       3       7
                                       0.00       0.00       0.00       3       8
                                       0.00       0.00       0.00       3       9
                                       0.00       0.00       0.00       3      10
                                       0.00       0.00       0.00       3      11
RTI-112       nma-04-356             -10.02      -7.70     -18.75       4       0
RTI-112       nma-12-269             -10.02      -2.04     -17.43       4       1
RTI-112       md2-02-251             -10.02      -4.16     -18.11       4       2
RTI-112       md2-03-020             -10.02      -5.53     -18.66       4       3
RTI-112       md2-03-112             -10.02      -4.62     -17.90       4       4
RTI-112       md2-05-001r            -10.02      10.61     -18.17       4       5
RTI-112       md2-02-424             -10.02      -6.75     -14.45       4       6
RTI-112       md2-04-136             -10.02      -1.42     -17.53       4       7
RTI-112       md2-04-432             -10.02       5.71     -19.63       4       8
RTI-112       nma-12-269r            -10.02       6.29     -21.19       4       9
RTI-112       md2-02-366             -10.02      -7.40     -15.28       4      10
RTI-112       nma-10-060             -10.02       0.20     -16.08       4      11
RTI-121       nma-04-080              -8.23     -13.27     -19.92       5       0
RTI-121       md2-02-121              -8.23      -6.91     -21.20       5       1
RTI-121       md2-01-352              -8.23      -3.91     -20.06       5       2
RTI-121       md2-02-008              -8.23      -7.47     -20.42       5       3
RTI-121       md2-03-176              -8.23     -10.52     -20.31       5       4
RTI-121       md2-03-414              -8.23      -8.16     -21.51       5       5
RTI-121       md2-02-161              -8.23     -10.90     -18.38       5       6
RTI-121       md2-02-385              -8.23       0.52     -16.90       5       7
RTI-121       nma-09-401              -8.23      -9.56     -18.10       5       8
RTI-121       nma-10-395              -8.23      -2.74     -17.79       5       9
                                       0.00       0.00       0.00       5      10
                                       0.00       0.00       0.00       5      11
RTI-311       nma-10-120              -9.19     -13.43     -14.87       6       0
RTI-311       md2-02-009              -9.19      -6.89     -15.64       6       1
RTI-311       mod-22-300              -9.19     -12.77     -16.03       6       2
                                       0.00       0.00       0.00       6       3
                                       0.00       0.00       0.00       6       4
                                       0.00       0.00       0.00       6       5
                                       0.00       0.00       0.00       6       6
                                       0.00       0.00       0.00       6       7
                                       0.00       0.00       0.00       6       8
                                       0.00       0.00       0.00       6       9
                                       0.00       0.00       0.00       6      10
                                       0.00       0.00       0.00       6      11
CPT           mod-08-107              -7.82       4.24     -19.76       7       0
CPT           md2-02-359              -7.82      -3.74     -16.07       7       1
CPT           mod-22-290              -7.82       6.62     -16.84       7       2
CPT           nma-10-155              -7.82      -1.79     -13.30       7       3
CPT           nma-10-405              -7.82      -2.60     -15.99       7       4
                                       0.00       0.00       0.00       7       5
                                       0.00       0.00       0.00       7       6
                                       0.00       0.00       0.00       7       7
                                       0.00       0.00       0.00       7       8
                                       0.00       0.00       0.00       7       9
                                       0.00       0.00       0.00       7      10
                                       0.00       0.00       0.00       7      11

知道这里有什么问题吗?它是数据文件格式吗?

1 个答案:

答案 0 :(得分:0)

这是一些温和的固定代码。 myFile函数中csvFilelie_reccsv_recreadFile()存在问题。

否则,我用empty和结构赋值简化了记录初始化;我在地方使用了更简单/不同的循环索引;并添加了一些诊断打印。

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct csv
{
    char class_name[12];
    char member[18];
    double class_value;
    double member_value1;
    double member_value2;
    double calc_output1;  // Program I'm writing adds values here
    double calc_output2; // And here
};

static
int readFile(char *csvFile, struct csv *csv_rec, size_t max_records)
{
    /* code for reading file here - this works as planned.
       Reads csv file and makes 1D array of structs with up to max_records
       elements */
    FILE *dataFile = NULL;
    size_t idx = 0;
    size_t fldidx = 0;      // struct field index
    char fileLine[255] = {0};
    char *p = NULL;         // pointer to line

    // dataFile = fopen(csvFile, "r"); // Rename myFile -> csvFile; delete duplicate

    // Open the file set by the command line and read it into the file object
    dataFile = fopen(csvFile, "r");
    if (dataFile == NULL)
    {
        perror("Error opening data file.\n");
        exit(EXIT_FAILURE);     // Exit program if data file cannot be read by runtime service
    }

    while ((fgets(fileLine, sizeof(fileLine), dataFile)) != NULL)
    {
        size_t len = strlen(fileLine);
        if (len == 0)
            continue;
        fileLine[len - 1] = '\0';
        if (idx >= max_records)
            break;
        printf("[[%s]]\n", fileLine);
        fldidx = 0;     // reset field index for each line
        // Use strtok to separate each line into tokens on ','
        for (p = strtok(fileLine, ","); p != NULL; p = strtok(NULL, ","))
        {
            // Use fldidx to separate data into struct
            switch (fldidx)
            {
            case 0:
                // JL: lie_rec --> csv_rec
                strncpy(csv_rec[idx].class_name, p, strlen(p));
                break;
            case 1:
                strncpy(csv_rec[idx].member, p, strlen(p));
                break;
            case 2:
                csv_rec[idx].class_value = atof(p);
                break;
            case 3:
                csv_rec[idx].member_value1 = atof(p);
                break;
            case 4:
                csv_rec[idx].member_value2 = atof(p);
                break;
            }
            // Increment field index
            fldidx++;
        }
        // Increment record index
        idx++;
    }
    // Close dataFile object
    fclose(dataFile);
    return idx;
}

int main(int argc, char *argv[])
{
    int m_members = 25; // Bigger than it needs to be for any file
    int n_classes = 25; // Bigger than needs to be for any file
    int n_records = 75; // Later a function will count these
    struct csv csv_data[m_members][n_classes]; // Declare 2D array
    struct csv csv_read[n_records]; // 1D array of structs
    struct csv empty = { "           ", "                 ", 0.0, 0.0, 0.0, 0.0, 0.0 };

    // Initialize csv_data 2D array:
    for (int i = 0; i < m_members; i++)
    {
        for (int j = 0; j < n_classes; j++)
            csv_data[i][j] = empty;
    }

    // Initialize csv_read struct array
    for (int i = 0; i < n_records; i++)
        csv_read[i] = empty;

    if (argc != 2)
    {
        printf("Usage: ./optimization datafile.csv\n");
        return 1;
    }

    int n_recs = readFile(argv[1], csv_read, n_records);

    // Here is what I have so far. It doesn't work:
    // First, set member and class indices to zero
    int members = 0;
    int classes = 0;
    int max_members = 0;

    // Next, copy values held in first record to 0,0 index of 2D array
    csv_data[classes][members] = csv_read[0];

    // This is the part I'm not doing correctly:
    for (int i = 1; i < n_recs; i++)
    {
        assert(members < m_members && classes < n_classes);
        if (strcmp(csv_read[i].class_name, csv_read[i - 1].class_name) == 0)
        {
            members += 1;
            csv_data[classes][members] = csv_read[i];
            printf("[%d,%d] - A\n", classes, members);
        }
        else
        {
            if (members > max_members)
                max_members = members;
            members = 0;
            classes += 1;
            csv_data[classes][members] = csv_read[i];
            printf("[%d,%d] - B\n", classes, members);
        }
    }

    printf("%-12s  %-18s  %9s  %9s  %9s  %6s  %6s\n",
           "Class", "Member", "C-Value", "M-Value 1", "M-Value 2", "Class", "Member");
    for (int i = 0; i < classes; i += 1)
    {
        for (int j = 0; j < max_members; j += 1)
        {
            printf("%-12s  %-18s  %9.2f  %9.2f  %9.2f  %6d  %6d\n",
                   csv_data[i][j].class_name, csv_data[i][j].member,
                   csv_data[i][j].class_value, csv_data[i][j].member_value1,
                   csv_data[i][j].member_value2, i, j);
        }
    }

    return 0;
}

对于此数据文件(部分随机生成,部分系统编辑):

Eeikehkt,Juxeizdiybnc,20.07,985.12,8816.17
Eeikehkt,Juxeizdiybnc,40.07,385.12,5816.17
Eeikehkt,Juxeizdiybnc,60.07,485.12,2816.17
Iamtppjo,Duxacewxhh,61.79,385.93,2477.32
Iamtppjo,Duxacewxhh,41.79,385.93,2477.32
Iamtppjo,Duxacewxhh,91.79,385.93,2477.32
Iamtppjo,Duxacewxhh,21.79,385.93,2477.32
Harbegghs,Javqaqetlmf,66.53,103.14,6106.43
Harbegghs,Javqaqetlmf,56.53,103.14,7106.43
Harbegghs,Javqaqetlmf,46.53,103.14,8106.43
Harbegghs,Javqaqetlmf,36.53,103.14,9106.43
Harbegghs,Javqaqetlmf,26.53,103.14,1106.43
Harbegghs,Javqaqetlmf,16.53,103.14,2106.43
Zumnyqmiq,Luoyjcvvdtwh,36.89,435.08,5337.35
Zumnyqmiq,Luoyjcvvdtwh,56.89,435.08,5337.35
Zumnyqmiq,Luoyjcvvdtwh,76.89,435.08,5337.35
Zagahwfn,Hanhmrcdgryn,84.58,598.20,8854.05
Keivsvmcb,Maaqjraizoaz,36.60,316.95,4320.89
Hoawiopqby,Puqezsvrscs,44.77,131.01,4315.89
Zifummkfm,Uitgzpnziz,94.29,342.45,2152.53
Fikwzidv,Iamjbgihhrb,59.63,915.11,9885.05
Yutihgddt,Augpvalibavo,44.64,472.51,3092.39

我得到以下诊断输出:

[[Eeikehkt,Juxeizdiybnc,20.07,985.12,8816.17]]
[[Eeikehkt,Juxeizdiybnc,40.07,385.12,5816.17]]
[[Eeikehkt,Juxeizdiybnc,60.07,485.12,2816.17]]
[[Iamtppjo,Duxacewxhh,61.79,385.93,2477.32]]
[[Iamtppjo,Duxacewxhh,41.79,385.93,2477.32]]
[[Iamtppjo,Duxacewxhh,91.79,385.93,2477.32]]
[[Iamtppjo,Duxacewxhh,21.79,385.93,2477.32]]
[[Harbegghs,Javqaqetlmf,66.53,103.14,6106.43]]
[[Harbegghs,Javqaqetlmf,56.53,103.14,7106.43]]
[[Harbegghs,Javqaqetlmf,46.53,103.14,8106.43]]
[[Harbegghs,Javqaqetlmf,36.53,103.14,9106.43]]
[[Harbegghs,Javqaqetlmf,26.53,103.14,1106.43]]
[[Harbegghs,Javqaqetlmf,16.53,103.14,2106.43]]
[[Zumnyqmiq,Luoyjcvvdtwh,36.89,435.08,5337.35]]
[[Zumnyqmiq,Luoyjcvvdtwh,56.89,435.08,5337.35]]
[[Zumnyqmiq,Luoyjcvvdtwh,76.89,435.08,5337.35]]
[[Zagahwfn,Hanhmrcdgryn,84.58,598.20,8854.05]]
[[Keivsvmcb,Maaqjraizoaz,36.60,316.95,4320.89]]
[[Hoawiopqby,Puqezsvrscs,44.77,131.01,4315.89]]
[[Zifummkfm,Uitgzpnziz,94.29,342.45,2152.53]]
[[Fikwzidv,Iamjbgihhrb,59.63,915.11,9885.05]]
[[Yutihgddt,Augpvalibavo,44.64,472.51,3092.39]]
[0,1] - A
[0,2] - A
[1,0] - B
[1,1] - A
[1,2] - A
[1,3] - A
[2,0] - B
[2,1] - A
[2,2] - A
[2,3] - A
[2,4] - A
[2,5] - A
[3,0] - B
[3,1] - A
[3,2] - A
[4,0] - B
[5,0] - B
[6,0] - B
[7,0] - B
[8,0] - B
[9,0] - B

后面是以下主要输出:

Class         Member                C-Value  M-Value 1  M-Value 2   Class  Member
Eeikehkt      Juxeizdiybnc            20.07     985.12    8816.17       0       0
Eeikehkt      Juxeizdiybnc            40.07     385.12    5816.17       0       1
Eeikehkt      Juxeizdiybnc            60.07     485.12    2816.17       0       2
                                       0.00       0.00       0.00       0       3
                                       0.00       0.00       0.00       0       4
Iamtppjo      Duxacewxhh              61.79     385.93    2477.32       1       0
Iamtppjo      Duxacewxhh              41.79     385.93    2477.32       1       1
Iamtppjo      Duxacewxhh              91.79     385.93    2477.32       1       2
Iamtppjo      Duxacewxhh              21.79     385.93    2477.32       1       3
                                       0.00       0.00       0.00       1       4
Harbegghs     Javqaqetlmf             66.53     103.14    6106.43       2       0
Harbegghs     Javqaqetlmf             56.53     103.14    7106.43       2       1
Harbegghs     Javqaqetlmf             46.53     103.14    8106.43       2       2
Harbegghs     Javqaqetlmf             36.53     103.14    9106.43       2       3
Harbegghs     Javqaqetlmf             26.53     103.14    1106.43       2       4
Zumnyqmiq     Luoyjcvvdtwh            36.89     435.08    5337.35       3       0
Zumnyqmiq     Luoyjcvvdtwh            56.89     435.08    5337.35       3       1
Zumnyqmiq     Luoyjcvvdtwh            76.89     435.08    5337.35       3       2
                                       0.00       0.00       0.00       3       3
                                       0.00       0.00       0.00       3       4
Zagahwfn      Hanhmrcdgryn            84.58     598.20    8854.05       4       0
                                       0.00       0.00       0.00       4       1
                                       0.00       0.00       0.00       4       2
                                       0.00       0.00       0.00       4       3
                                       0.00       0.00       0.00       4       4
Keivsvmcb     Maaqjraizoaz            36.60     316.95    4320.89       5       0
                                       0.00       0.00       0.00       5       1
                                       0.00       0.00       0.00       5       2
                                       0.00       0.00       0.00       5       3
                                       0.00       0.00       0.00       5       4
Hoawiopqby    Puqezsvrscs             44.77     131.01    4315.89       6       0
                                       0.00       0.00       0.00       6       1
                                       0.00       0.00       0.00       6       2
                                       0.00       0.00       0.00       6       3
                                       0.00       0.00       0.00       6       4
Zifummkfm     Uitgzpnziz              94.29     342.45    2152.53       7       0
                                       0.00       0.00       0.00       7       1
                                       0.00       0.00       0.00       7       2
                                       0.00       0.00       0.00       7       3
                                       0.00       0.00       0.00       7       4
Fikwzidv      Iamjbgihhrb             59.63     915.11    9885.05       8       0
                                       0.00       0.00       0.00       8       1
                                       0.00       0.00       0.00       8       2
                                       0.00       0.00       0.00       8       3
                                       0.00       0.00       0.00       8       4

如果这不是您所期望的,请显示一些示例数据和所需的输出。

继续调试

上面的代码省略了打印最后处理的类,如评注中所述。我做了一些更多变量重命名并避免了初始化循环。使用class_idx(对于数组中的当前类索引)和num_classes对于类的数量应该使代码更容易理解。我还添加了一个class_size数组来记录每个类中有多少条目。代码还会仔细地从行尾删除回车。它仍会跳过空数据行(只有一行结尾的数据行)。我删除了两个“未使用的”结构成员calc_output1calc_output2,因为它们与此代码无关。我已经使调试输出以变量debug的值为条件,在此代码中设置为0。您可以安排通过命令行参数或环境变量将其设置为一个。

我还清理了strncpy()函数中readFile()的使用情况。它没有做你想要的 - 它没有提供溢出保护,因为你指定可用长度是源字符串的长度,而不是目标字符串的长度。事实上,它还确保strncpy()不是null终止复制的字符串,留下空白填充(因为初始化循环 - 在本修订版中删除) - 鉴于表格输出很难发现。我相信safer_copy()函数正确封装了操作。它认为过长的名字是致命的错误;如果您愿意,可以选择截断。然后我使用memmove()(或者memcpy())来复制数据,并手动空终止目标字符串。与大多数事情一样,有多种方法可以做到这一点(Perl座右铭 - 又名TMTOWTDI),您需要自己选择最适合您需求的方式。

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct csv
{
    char class_name[12];
    char member[18];
    double class_value;
    double member_value1;
    double member_value2;
};

static int debug = 0;

static
void safer_copy(const char *p, char *dst, size_t dst_size, const char *tag)
{
    if (strlen(p) >= dst_size)
    {
        fprintf(stderr, "Overlong %s [%s] (%zu vs %zu maximum)\n",
                tag, p, strlen(p), dst_size - 1);
        exit(EXIT_FAILURE);
    }
    strcpy(dst, p);
}

static
int readFile(char *csvFile, struct csv *csv_rec, size_t max_records)
{
    FILE *dataFile = NULL;
    size_t idx = 0;
    char fileLine[255] = {0};

    dataFile = fopen(csvFile, "r");
    if (dataFile == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", csvFile);
        exit(EXIT_FAILURE);
    }

    for (idx = 0; fgets(fileLine, sizeof(fileLine), dataFile) != NULL; idx++)
    {
        size_t len = strlen(fileLine);
        if (len == 0)                   // Should never occur
            continue;
        assert(fileLine[len - 1] == '\n');
        fileLine[--len] = '\0';
        if (len == 0)                   // Could occur for empty line
            continue;
        if (fileLine[len - 1] == '\r')  // Detect CRLF line endings too
            fileLine[--len] = '\0';
        if (len == 0)                   // Could occur for empty line
            continue;
        if (idx >= max_records)
            break;
        if (debug) printf("[[%s]]\n", fileLine);
        char *data = fileLine;
        char *p;
        for (size_t fldidx = 0; (p = strtok(data, ",")) != NULL; data = NULL, fldidx++)
        {
            switch (fldidx)
            {
            case 0:
                safer_copy(p, csv_rec[idx].class_name,
                           sizeof(csv_rec[idx].class_name), "class name");
                break;
            case 1:
                safer_copy(p, csv_rec[idx].member,
                           sizeof(csv_rec[idx].member), "member");
                break;
            case 2:
                csv_rec[idx].class_value = atof(p);
                break;
            case 3:
                csv_rec[idx].member_value1 = atof(p);
                break;
            case 4:
                csv_rec[idx].member_value2 = atof(p);
                break;
            }
        }
    }
    fclose(dataFile);
    return idx;
}

int main(int argc, char *argv[])
{
    int max_members = 25;
    int max_classes = 25;
    int max_records = 75;
    struct csv csv_data[max_members][max_classes];
    struct csv csv_read[max_records];
    int class_size[max_members];

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s datafile.csv\n", argv[0]);
        return 1;
    }

    int num_records = readFile(argv[1], csv_read, max_records);
    if (num_records == 0)
    {
        fprintf(stderr, "%s: empty data file %s\n", argv[0], argv[1]);
        return 1;
    }

    int member_idx = 0;
    int class_idx = 0;
    int max_group = 0;

    csv_data[class_idx][member_idx] = csv_read[0];

    for (int i = 1; i < num_records; i++)
    {
        assert(member_idx < max_members && class_idx < max_classes);
        if (strcmp(csv_read[i].class_name, csv_read[i - 1].class_name) == 0)
            member_idx++;
        else
        {
            if (member_idx > max_group)
                max_group = member_idx;
            class_size[class_idx++] = member_idx + 1;
            member_idx = 0;
        }
        csv_data[class_idx][member_idx] = csv_read[i];
        if (debug)
            printf("[%d,%d] - %s\n", class_idx, member_idx, csv_read[i].class_name);
    }
    class_size[class_idx] = member_idx + 1;
    int num_classes = class_idx + 1;
    if (debug)
        printf("Classes = %d, max members = %d\n", num_classes, max_group);

    printf("%-12s  %-18s  %9s  %9s  %9s  %6s  %6s\n",
           "Class", "Member", "C-Value", "M-Value 1", "M-Value 2", "Class", "Member");
    for (int i = 0; i < num_classes; i++)
    {
        for (int j = 0; j < class_size[i]; j++)
        {
            printf("%-12s  %-18s  %9.2f  %9.2f  %9.2f  %6d  %6d\n",
                   csv_data[i][j].class_name, csv_data[i][j].member,
                   csv_data[i][j].class_value, csv_data[i][j].member_value1,
                   csv_data[i][j].member_value2, i, j);
        }
    }

    return 0;
}

这表明你几乎总能磨练一个程序。我并不是说我想象中的任何一个都是完美的。例如,如果一行缺少某些字段,则会在记录中存储任意垃圾;代码不会修剪名称字段中的前导或尾随空白。

在问题的样本数据上,输出为:

Class         Member                C-Value  M-Value 1  M-Value 2   Class  Member
RTI-31        nma-10-325              -9.19      -1.70     -17.76       0       0
RTI-31        nma-04-176              -9.19      -0.71     -17.30       0       1
RTI-31        nma-04-176r             -9.19      -1.78     -18.89       0       2
RTI-31        md2-02-280              -9.19      -6.72     -17.31       0       3
RTI-31        nma-10-346              -9.19     -11.25     -15.85       0       4
RTI-31        nma-04-263              -9.19     -11.71     -15.04       0       5
RTI-31        nma-08-195              -9.19      -4.28     -14.86       0       6
RTI-31        nma-04-009              -9.19      -9.96     -15.38       0       7
RTI-32        nma-10-088              -8.12       3.40     -13.82       1       0
RTI-32        nma-04-394              -8.12       5.88     -19.00       1       1
RTI-32        nma-08-230              -8.12       0.41     -17.51       1       2
RTI-32        md2-01-186              -8.12       2.30     -18.42       1       3
RTI-32        md2-02-029              -8.12      -0.85     -19.88       1       4
RTI-32        md2-03-113              -8.12      -2.13     -17.89       1       5
RTI-32        md2-03-408              -8.12      -2.38     -19.10       1       6
RTI-32        nma-08-230r             -8.12      -3.52     -15.81       1       7
RTI-32        md2-02-440              -8.12      -1.19     -19.54       1       8
RTI-32        nma-10-450              -8.12      -8.15     -16.32       1       9
RTI-55        nma-10-001             -10.82      -5.53     -21.43       2       0
RTI-55        mod-15-206             -10.82      -7.89     -15.78       2       1
RTI-55        mod-15-315             -10.82      -8.86     -14.75       2       2
RTI-55        md2-02-326             -10.82      -5.71     -17.27       2       3
RTI-55        md2-02-385-2ns         -10.82      -4.12     -19.36       2       4
RTI-55        md2-02-385             -10.82      -4.95     -18.98       2       5
RTI-55        mod-20-399             -10.82     -10.22     -16.33       2       6
RTI-55        nma-04-221             -10.82     -10.72     -16.92       2       7
RTI-55        nma-10-386             -10.82      -1.86     -16.20       2       8
RTI-83        nma-10-442              -8.78      -2.05     -15.32       3       0
RTI-83        nma-07-088              -8.78      -0.54     -15.73       3       1
RTI-83        md2-02-373              -8.78      -1.91     -16.11       3       2
RTI-83        nma-08-131              -8.78       0.31     -19.40       3       3
RTI-83        nma-08-496              -8.78       1.26     -19.86       3       4
RTI-83        nma-08-496r             -8.78      -3.21     -19.78       3       5
RTI-83        nma-10-083              -8.78      -1.39     -16.46       3       6
RTI-112       nma-04-356             -10.02      -7.70     -18.75       4       0
RTI-112       nma-12-269             -10.02      -2.04     -17.43       4       1
RTI-112       md2-02-251             -10.02      -4.16     -18.11       4       2
RTI-112       md2-03-020             -10.02      -5.53     -18.66       4       3
RTI-112       md2-03-112             -10.02      -4.62     -17.90       4       4
RTI-112       md2-05-001r            -10.02      10.61     -18.17       4       5
RTI-112       md2-02-424             -10.02      -6.75     -14.45       4       6
RTI-112       md2-04-136             -10.02      -1.42     -17.53       4       7
RTI-112       md2-04-432             -10.02       5.71     -19.63       4       8
RTI-112       nma-12-269r            -10.02       6.29     -21.19       4       9
RTI-112       md2-02-366             -10.02      -7.40     -15.28       4      10
RTI-112       nma-10-060             -10.02       0.20     -16.08       4      11
RTI-112       nma-10-009             -10.02      -8.50     -15.47       4      12
RTI-121       nma-04-080              -8.23     -13.27     -19.92       5       0
RTI-121       md2-02-121              -8.23      -6.91     -21.20       5       1
RTI-121       md2-01-352              -8.23      -3.91     -20.06       5       2
RTI-121       md2-02-008              -8.23      -7.47     -20.42       5       3
RTI-121       md2-03-176              -8.23     -10.52     -20.31       5       4
RTI-121       md2-03-414              -8.23      -8.16     -21.51       5       5
RTI-121       md2-02-161              -8.23     -10.90     -18.38       5       6
RTI-121       md2-02-385              -8.23       0.52     -16.90       5       7
RTI-121       nma-09-401              -8.23      -9.56     -18.10       5       8
RTI-121       nma-10-395              -8.23      -2.74     -17.79       5       9
RTI-311       nma-10-120              -9.19     -13.43     -14.87       6       0
RTI-311       md2-02-009              -9.19      -6.89     -15.64       6       1
RTI-311       mod-22-300              -9.19     -12.77     -16.03       6       2
CPT           mod-08-107              -7.82       4.24     -19.76       7       0
CPT           md2-02-359              -7.82      -3.74     -16.07       7       1
CPT           mod-22-290              -7.82       6.62     -16.84       7       2
CPT           nma-10-155              -7.82      -1.79     -13.30       7       3
CPT           nma-10-405              -7.82      -2.60     -15.99       7       4
CFT           mod-08-220              -8.45      -3.41     -18.91       8       0
CFT           md2-02-111              -8.45      -6.57     -14.84       8       1