美好的一天,
所以目前我有这个文件并包含:实际文件是这样的
1,name A. lname2,Das F. Esd3,Frsas A. Casdfre4,Rsadna P. Tsdaas5,Asadla C. Toasdtino6,Aasdel P. Gasdla7,Masda Isable A. Milasdroso8,Niasdkie T. Niasdemus9,Evasdn A. Vasdueva10,Geasdlyn C. Iasdncio11,Aasdr Leasdma12,Neasdio A. Maasdbale
我在输出时遇到问题,这是我当前的代码
printf("\nID\tName\n");
while(fscanf(load, "%[^,],%[^1-9]", faculty[counter].id, faculty[counter].name)!=EOF) {
printf("%s\t%s", faculty[counter].id, faculty[counter].name);
输出如下:
ID Name
1 asdasd
2 asdas
3 asdsad4 othername
5 asdsad
6 asdasda
7 sdfsdf
8 sadsad
9 asdsad
10 asdas
11 asdsad12 asdas
4,12 has invalid position.
输出应该是一个范围:
1 ID Name
1 asdasd
2 asdas
3 asdsad
4 othername
5 asdsad
6 asdasda
7 sdfsdf
8 sadsad
9 asdsad
10 asdas
11 asdsad
12 asdas
可能是什么问题?这是我第一次使用这样的分隔符,你可以解释一下这个问题是什么吗?谢谢!
答案 0 :(得分:0)
将格式更改为:
printf("\nID\tName\n");
while (fscanf(load, " %[0-9], %[^0-9]", faculty[counter].id, faculty[counter].name) == 2) {
printf("%s\t%s\n", faculty[counter].id, faculty[counter].name);
...
counter++;
}
请注意,您还应该传递要存储到目标数组的最大字符数,以避免潜在的缓冲区溢出。
但请注意,问题中发布的示例输出与代码片段不一致:您不以printf
格式输出换行符并确认数据文件中没有换行符,换行符在何处输出来自?
你能用假名来制作一个显示问题的测试文件吗?同时发布失败的完整代码。结构定义也很重要。没有精确的数据和代码,很难设置诊断。
答案 1 :(得分:0)
这种情况下单独使用fscanf
进行阅读可以起作用,但缺乏通过一次读取整行然后使用sscanf
解析该行或仅仅走一对来实现的稳健性选择id
和name
对的字符指针。
要在您作为输入发布的行上使用fscanf
,您可以在重复调用"%d,%[^0-9]"
时使用fscanf
的格式说明符。 (如果name超过数组大小,则应提供 field-width 修饰符以防止溢出)。例如,您可以执行以下操作来获取每个id
和name
对(这些只是在下面的示例中输出):
#include <stdio.h>
enum { MAXNM = 64 }; /* constant for max characters in name */
int main (int argc, char **argv) {
int id;
char name[MAXNM] = "";
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read each 'id,name' pair (name cannot include digits) */
while (fscanf (fp, "%d,%63[^0-9]", &id, name) == 2)
printf ("%3d %s\n", id, name);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
示例使用/输出
$ ./bin/rd_num_name <dat/num_names.txt
1 name A. lname
2 Das F. Esd
3 Frsas A. Casdfre
4 Rsadna P. Tsdaas
5 Asadla C. Toasdtino
6 Aasdel P. Gasdla
7 Masda Isable A. Milasdroso
8 Niasdkie T. Niasdemus
9 Evasdn A. Vasdueva
10 Geasdlyn C. Iasdncio
11 Aasdr Leasdma
12 Neasdio A. Maasdbale
如果您想使用带有fgets
或getline
的面向行的输入来阅读整行,然后解析每个id
和{{1}从保存整行的缓冲区中,您可以执行以下操作。读取整行,然后解析的好处是它将读取与解析分离,允许您验证两者。此外,在输入格式略有不同的情况下,您的阅读不受匹配失败的影响。
此处,使用name
并使用sscanf
格式说明符来确定每次调用%n
所消耗的字符数,您可以使用指针选择sscanf
和id
对,例如
name
注意:输出相同。