fscanf() 读取带格式行空格的字符串

fscanf() reading string with spaces in formatted lines

使用这种结构:

typedef struct sProduct{
  int code;
  char description[40];
  int price;
};

我想读取一个格式为 txt 的文件:

1,Vino Malbec,12

其中格式为:code,description,price。但是当它有 space.

时,我无法阅读描述

我试过这个:

fscanf(file,"%d,%[^\n],%d\n",&p.code,&p.description,&p.price);

代码保存正常,但描述中正在保存 Vino Malbec,12,当时我只想保存 Vino Malbec 因为 12 是价格。

有什么帮助吗? 谢谢!

主要问题是"%[^\n],""%[^\n]" 扫描除 '\n' 之外的所有内容,因此 description 扫描 ','。当遇到逗号时,代码需要停止扫描到 description

对于面向行的文件数据,第一次读取 1 行。

char buf[100];
if (fgets(buf, sizeof buf, file) == NULL) Handle_EOForIOError();

然后扫一扫。使用 %39[^,] 不扫描 ',' 并将宽度限制为 39 char.

int cnt = sscanf(buf,"%d , %39[^,],%d", &p.code, p.description, &p.price);
if (cnt != 3) Handle_IllFormattedData();

另一个妙招是:使用" %n"记录解析结束。

int n = 0;
sscanf(buf,"%d , %39[^,],%d %n", &p.code, p.description, &p.price, &n);
if (n == 0 || buf[n]) Handle_IllFormattedData_or_ExtraData();

[编辑]

简化:@user3386109

更正:@cool-guy 删除 &

@chux 已经对此发表了很好的回答,但是如果您需要使用 fscanf,请使用

if(fscanf(file,"%d,%39[^,],%d",&p.code,p.description,&p.price)!=3)
    Handle_Bad_Data();

这里,fscanf首先扫描一个数字(%d),然后将其放入p.code。然后,它扫描一个逗号(并丢弃它),然后扫描最多 39 个字符或直到一个逗号并将所有内容放入 p.description。然后,它扫描一个逗号(并丢弃它),然后扫描一个数字(%d)并将其放入 p.price.