将 CSV 文件中的值读入变量 [英] Reading values from CSV file into variables

查看:32
本文介绍了将 CSV 文件中的值读入变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一段简单的代码来从一个 CSV 文件中读取值,最多 100 个条目到一个结构数组中.

CSV 文件的一行示例:

1,Mr,James,Quigley,Director,200000,0

我使用以下代码读入值,但是当我打印出这些值时它们不正确

for(i = 0; i < 3; i++)/*这里只是假设条目数来演示问题*/{fscanf(f, "%d,%s,%s,%s,%s,%d,%d", &inArray[i].ID, inArray[i].salutation, inArray[i].firstName,inArray[i].surName, inArray[i].position, &inArray[i].sal, &inArray[i].deleted);}

然后当我打印出名字时,所有值都分配给名字:

for(j = 0; j <3; j++)/* 通过打印值进行测试*/{printf("员工姓名是 %s
", inArray[j].firstName);}

以这种方式给出 ames,Quigley,Director,200000,0 等等.我确定这就是我格式化 fscanf 行的方式,但我无法让它工作.

这是我正在阅读的结构:

typedef struct Employee{整数标识;字符称呼[4];字符名字[21];字符姓氏[31];字符位置[16];国际萨尔;int 删除;} 员工;

解决方案

这是因为字符串 %s 可以包含逗号,所以它会被扫描到第一个字符串中.scanf() 格式说明符中没有前瞻",在格式说明字符串中 %s 后跟逗号的事实没有任何意义.>

使用字符组(在手册中搜索[).

const int got = fscanf(f, "%d,%[^,],%[^,],%[^,],%[^,],%d,%d", &inArray[i].ID,inArray[i].salutation, inArray[i].firstName,inArray[i].surName, inArray[i].position, &inArray[i].sal,&inArray[i].deleted);

并学习检查返回值,因为 I/O 调用可能会失败!除非 got 为 7,否则不要依赖数据是否有效.

为了让您的程序读取整个文件(多条记录,即行),我建议使用 fgets() 将整行加载到(大)固定大小的缓冲区中,然后使用 sscanf() 在该缓冲区上解析列值.这更容易,并且将确保您真正扫描单独的行,在循环中调用 fscanf() 不会,因为对于 fscanf() 换行只是空白.

I am trying to write a simple piece of code to read values from a CSV file with a max of 100 entries into an array of structs.

Example of a line of the CSV file:

1,Mr,James,Quigley,Director,200000,0

I use the following code to read in the values, but when I print out the values they are incorrect

for(i = 0; i < 3; i++) /*just assuming number of entries here to demonstrate problem*/
    {
    fscanf(f, "%d,%s,%s,%s,%s,%d,%d", &inArray[i].ID, inArray[i].salutation, inArray[i].firstName, inArray[i].surName, inArray[i].position, &inArray[i].sal, &inArray[i].deleted);
    } 

Then when I print out the first name, the values are all assigned to the first name:

for(j = 0; j < 3; j++) /* test by printing values*/
    {
    printf("Employee name is %s
", inArray[j].firstName);
    } 

Gives ames,Quigley,Director,200000,0 and so on in that way. I am sure it's how i format the fscanf line but I can't get it to work.

Here is my struct I'm reading into:

typedef struct Employee
    {
    int ID;
    char salutation[4];
    char firstName[21];
    char surName[31];
    char position[16];
    int sal;
    int deleted;
    } Employee;

解决方案

This is because a string %s can contain the comma, so it gets scanned into the first string. There's no "look-ahead" in the scanf() formatting specifier, the fact that the %s is followed by a comma in the format specification string means nothing.

Use character groups (search the manual for [).

const int got = fscanf(f, "%d,%[^,],%[^,],%[^,],%[^,],%d,%d", &inArray[i].ID,
                       inArray[i].salutation, inArray[i].firstName,
                       inArray[i].surName, inArray[i].position, &inArray[i].sal, 
                       &inArray[i].deleted);

And learn to check the return value, since I/O calls can fail! Don't depend on the data being valid unless got is 7.

To make your program read the entire file (multiple records, i.e. lines), I would recommend loading entire lines into a (large) fixed-size buffer with fgets(), then using sscanf() on that buffer to parse out the column values. That is much easier and will ensure that you really do scan separate lines, calling fscanf() in a loop will not, since to fscanf() a linefeed is just whitespace.

这篇关于将 CSV 文件中的值读入变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆