[英]How do i get fscanf to read from a .csv file, reading each section in between the commas and on each line into a string?
I'm writing a program to read a map from a .csv file, and I want to read each section of the file and then write the information from it into a relevant struct in a 2D array. 我正在编写一个程序以从.csv文件中读取地图,并且我想读取文件的每个部分,然后将其信息写入2D数组中的相关结构中。 I use fscanf to get the number of rows and columns to malloc the array of structs, and I can read the first value up until the comma and deal with it.
我使用fscanf获取行数和列数以malloc分配结构数组,并且我可以读取第一个值直到逗号为止并对其进行处理。 However, there can also be blank fields, that appear in a line such as 1 goat,,2 cat My program reads the 1 and goat and deals with that, but then the next thing it scans is just cat.
但是,也可能有空白字段,它们出现在一行中,例如1只山羊,2只猫。我的程序读取1和山羊并对其进行处理,但是接下来扫描的只是猫。 I want it to read the 2 commas, recognize there's nothing in them, and then move on to the cat and read that before moving on to the next line
我希望它阅读两个逗号,识别其中没有任何内容,然后继续阅读并阅读猫,然后再继续下一行
I don't know how to do the correct format specifications for the fscanf. 我不知道如何为fscanf做正确的格式规范。 Currently I've got
fscanf(fp, "%[^,]", animal);
目前,我有
fscanf(fp, "%[^,]", animal);
/*scans file until comma, writes the scanned text into array*/
fscanf(fp, "%[^,]", animal);
printf("Scanned in string for y (%d) and x %d = (%s)\n", j, k, anima;l);
if (strcmp(animal, "") != 0)
{
/*if first character is lowercase, change to upper)*/
if(animal[0]>90)
{
animal[0]=animal[0]-32;
}
/*Checks if item is cat goat or mouse by checking 1st letter of the scanned in array is C G or M*/
if(strncmp(animal,"C", 1) == 0)
{
/*copies name of the animal into the struct*/
strcpy(animalarray[j][k].name, "Cat");
/*write animal name into struct*/
token =strtok(animal, spaceDelimeter);
/* The 1 is already dealt with, can be moved past*/
token = strtok(NULL, commaDelimeter);
printf("token = %s\n", token);
animalarray[j][k].number= atoi(token);
printf("Animal is %s, number is %d\n", animalarray[j][k].name, animalarray[j][k].number);
}
The Input File is ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 输入文件是~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2,3 1 goat,,2 cat 3 mouse, 5 goat, 2,3 1只山羊,, 2只猫3只老鼠,5只山羊,
The output when i run is 我运行时的输出是
rows 2, columns 3
Scanned in string for row 0 and column 0 = 1 goat
token = goat
Animal is goat, number is 1
Scanned in string for row 0 and column 1 = 2
token = (null)
Segmentation fault (core dumped)
it should be 它应该是
...
Scanned in string for row 0 and column 1 = "blank"
Scanned in string for row 0 and column 1 = 2 cat
...
fscanf
cannot scan empty strings, but you can use the return value to detect whether there was anything scanned at all: fscanf
无法扫描空字符串,但是您可以使用返回值来检测是否扫描了所有内容:
FILE *f = fopen(filename, "r");
char buf[80];
int row = 0;
int col = 0;
while (1) {
int n = fscanf(f, "%79[^,\n]", buf);
if (n == EOF) break;
if (n == 0) *buf = '\0';
printf("[%d, %d] '%s'\n", row, col, buf);
if (fgetc(f) == ',') {
col++;
} else {
col = 0;
row++;
}
}
If nothing was acanned, n
is 0- In that case, the code explicitly clears the input string by writing the null terminator in the first char. 如果未设置任何内容,则
n
为0-在这种情况下,代码通过在第一个字符中写入空终止符来显式清除输入字符串。 Rows and columns are detected by whether an comma or a newline was read. 通过读取逗号还是换行来检测行和列。 (The next character can only be a comma, a newline or the end of the file.)
(下一个字符只能是逗号,换行符或文件结尾。)
Another possibility is to read the input line-wise with fgets
and then scan each line. 另一种可能性是使用
fgets
逐行读取输入,然后扫描每一行。 The string scanning function sscanf
has the same limitations as fscanf
, so it might be better to use string functions, such as strchr
. 字符串扫描函数
sscanf
与fscanf
具有相同的限制,因此最好使用字符串函数,例如strchr
。 Here I have used strcspn
from <string.h>
, which counts the characters in a string until any of the given characters or the end of the string are found. 在这里,我使用
strcspn
来自<string.h>
strcspn
,它对字符串中的字符进行计数,直到找到任何给定的字符或字符串的末尾。 That makes it very similar to the %[^n ...]
format in fscanf
: 这使其与
fscanf
的%[^n ...]
格式非常相似:
FILE *f = fopen(filename, "r");
char line[80];
int row = 0;
while (fgets(line, sizeof(line), f)) {
int col = 0;
int offset = 0;
while (line[offset]) {
int next = strcspn(line + offset, ",\n");
printf("[%d, %d] '%.*s'\n", row, col, next, line + offset);
offset += next + 1;
col++;
}
row++;
}
Again, column and line detection are by context. 同样,列和行检测是根据上下文进行的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.