我写了一个函数,成功读取每个记录使用以下格式的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
知道这里有什么问题吗?它是数据文件格式吗?
答案 0 :(得分:0)
这是一些温和的固定代码。 myFile
函数中csvFile
与lie_rec
和csv_rec
与readFile()
存在问题。
否则,我用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_output1
和calc_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