我必须使用此文件信息Cigaretas,吸烟,1,5.500000伍兹,因杜烟囱,2,100.000000
要填充此结构:
typedef struct product{
char name[32];
char about_product[32];
int product_id;
double price;
}sProduct;
使用此功能:
void print_prod(){
sProduct ptr;
FILE *fp=fopen("product.txt", "r");
int cnt=1;
do{
fscanf(fp, "%s,%s,%d,%g\n", ptr.name, ptr.about_product, &ptr.product_id, &ptr.price);
cnt++;
}while(!feof(fp));
fclose(fp);
}
但是它不是错误,因为我在txt文件中使用逗号作为分隔符。
这里有两个问题,都围绕scanf
处理%s
指令的方式:
您可以通过几种方法来完成已设置的输入任务,但是要继续使用scanf
要直接将特定输入扫描到数据结构中,您需要%[
指令而不是%s
。
%[
指令接受一个“扫描集”,该扫描集准确描述可能在字段中出现的字符,其中可以包括空格。这采用类似于正则表达式或glob字符类的形式。就像char
指令一样,相应的参数应该是指向%s
的指针。您还应该注意,与大多数指令(包括%s
)不同,%[
指令不会跳过前导空格。对您来说,它的用法可能像这样:
fscanf(fp, "%[^,],%[^,],%d,%g\n", ptr.name, ptr.about_product, &ptr.product_id, &ptr.price);
[两个%[^,]
字段描述符分别扫描除逗号(,
)以外的任意数量的字符。
此外,明智的做法是指定字段宽度,以免在数据中出现太长的字段时避免超出数组的范围。由于您提供了32个字节的数组,并且每个字符串的一个字节必须保留给一个字符串终止符,所以可能是这样的:
fscanf(fp, "%31[^,],%31[^,],%d,%g\n", ptr.name, ptr.about_product, &ptr.product_id, &ptr.price);
但是,与几乎所有具有任何故障模式的功能一样,还应该以编程方式检查该功能是否成功。您需要主动且一致地执行此操作,否则您的程序可能会以微妙且令人惊讶的方式失败。对于scanf
以及许多类似的用法,这意味着检查返回值是否等于格式中的输入指令的数量(返回值指示成功扫描和分配了多少个字段):
int fields;
fields = fscanf(fp, "%31[^,],%31[^,],%d,%g\n", ptr.name, ptr.about_product,
&ptr.product_id, &ptr.price);
if (fields != 4) {
// handle input error ...
}