[英]Reading, translating and writing data between multiple CSV files using C
我有 3 个 CSV 文件。 其中第一个包含 4 列:
ID,Section1,Section2,Secion3
1,23,12,7
2,11,26,9
. . . .
. . . .
19,30,22,4
20,5,6,16
第一列是 ID,其他三列包含从 0 到 30 的随机数。
下一个文件是“转换”文件。 它显示了每个数字的对应值:
30,45,44,45
29,44,42,43
28,43,42,41
. . . .
. . . .
1,22,21,22
0,20,21,21
第一列是要读取的数字,接下来的列是将替换每个部分中的这些数字的值。
例如,如果您在第 1 节中读到 30,它将被 45 替换,如果您在第 2 节中找到 29,它将被 42 替换,依此类推。
如果我要将转换后的数字写入具有相同 4 列格式的第三个 CSV 文件,我应该怎么做?
到目前为止,由于它们是随机的,除了“转换”文件之外,我在生成文件方面没有任何问题,但我不知道如何进行转换。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main (int argc,char *argv[]){
int i, num1;
char numbers[20][20];
char conversions[20][20];
//File with the initial numbers
FILE *registry = fopen("registry.csv","w+");
if (registry == NULL){
fputs ("File error",stderr);
exit (1);
}
//Conversion file
FILE *conversion = fopen("conversion.csv","r");
if (conversion == NULL){
fputs ("File error",stderr);
exit (1);
}
//File where the resulting values will be written
FILE *results = fopen("results.csv","a");
if (results == NULL){
fputs ("File error",stderr);
exit (1);
}
//Writing the headers
fprintf(results,"ID,Results1,Results2,Results3\n");
fprintf(registry,"ID,Section1,Section2,Section3\n");
srand(time(0));
//Generating the random numbers
for(i=1;i<21;i++){
sprintf(numbers[i],"%d,%d,%d,%d\n",i,rand()%31,rand()%31,
rand()%31);
fputs(numbers[i], registry);
}
//This is where I don't know how to proceed
for(i=1;i<21;i++){
sprintf(conversions[i],"%d,%d,%d,%d\n",i,
fscanf(registry,"%d,%*s,%*s,%*s\n",num1)...);
}
我试图通过将所有内容保存到缓冲区然后将其写入文件来执行类似于生成随机数的操作,我发现 fscanf function 可以很好地跳过我不需要的部分阅读,但我不知道如何使用它来跳过标题和 ID 列,我仍然缺少转换部分。
转换文件:
30,45,44,45
29,44,43,43
28,43,42,42
27,43,41,40
26,41,40,40
25,40,39,39
24,39,37,39
23,38,37,38
22,38,36,37
21,36,36,37
20,35,35,36
19,34,34,35
18,33,34,35
17,33,33,34
16,32,32,33
15,32,31,32
14,31,30,31
13,30,30,31
12,29,29,30
11,29,28,29
10,28,28,29
9,28,27,27
8,27,26,26
7,27,26,25
6,26,25,25
5,25,24,24
4,25,23,24
3,24,23,23
2,23,22,21
1,21,21,20
0,20,21,20
这个答案的范围是解决:
//This is where I don't know how to proceed
。
要执行您所描述的操作,如果不需要在注册表、结果或转换中包含第一列以进行存储,则不要。 尽管对人类可读性很好,但它们使读取和使用 arrays 的任务复杂化。 未使用的列数据和 header 行需要数组索引体操才能使数据正确排列到 arrays 中。 如果没有 header 行和编号列,仅数组索引就足以跟踪进行转换所需的所有内容。
但是,如果您觉得需要第一列/行来满足您的目的,则调整下面显示的例程的数组索引以适应。
以下步骤(其中一些您已经完成)是我认为对使转换步骤尽可能简单至关重要的步骤......
脚步:
创建注册表 - 60 - 随机数 (0-30) 排列成 20 行,3 个数据列
创建int reg[20][3] = {{0}};
fgets
sscanf
例程将注册表读入 reg 数组。示例:(假设您的代码中已经创建了注册表)
registry = fopen(".\\registry.csv","r");
if (registry)
{
while(fgets(buf, sizeof(buf), registry))
{
sscanf(buf, "%d,%d,%d", ®[index][0],®[index][1],®[index][2] );
index++;
}
fclose(registry);
}
转换表 - 预先存在的文件
创建int conv[31][3] = {{0}};
使用组合fgets
sscanf
例程将转换表读入 conv 数组(参见上面的示例)
正确创建这些 arrays 后,
执行转换:
创建int res[20][3] = {{0}};
创建char buf[80] = {0};
FILE *results = fopen(".\\results.csv","w");
例子:
//File where the resulting values will be written
FILE *results = fopen(".\\results.csv","w");
if (results)
{
for(i=0;i<sizeof(reg)/sizeof(reg[0]);i++)
{
for(j=0;j<sizeof(reg[0])/sizeof(reg[0][0]);j++)
{
res[i][j] = conv[reg[i][j]][j];
// | | |___reg col == conv col
// | |______value reg == conv row
// |________________________________row and column of conv
}
sprintf(buf, "%d,%d,%d\n", res[i][0],res[i][1],res[i][2]);
fputs(buf, results);
}
fclose(results);
}
此时,您可以以适合您需要的格式打印结果文件。
下图显示了使用上述建议方法对随机生成的registry
的实际结果、您为conversion
提供的值和results
。 (正如我在评论中所建议的那样,每个创建都没有在原始代码中显示第 1 列。)图像显示每组数组数据的索引从 0 到 n:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.