我试图在C中使用sscanf函数,但它不需要阅读格式,我已经阅读了该函数的文档并遵循了示例,但它对我来说仍然不太好,因此我想得到一些建议。。
int main() {
long int id;
float grade,age;
char name[40],city[40],country[40],line[100]="388891477tItzeltGardnert21t6tIrantTehran";
int read_items = sscanf(line,"%ld %*[t] %[a-zA-Z -] %*[t] %f %*[t] %f %*[t] %[a-zA-Z -] %*[t] %[a-zA-Z -]",
&id,name,&age,&grade,country,city);
printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d itemsn",id,name,grade,age,country,city,read_items);
}
电流输出:
readed line is: 3888914775 0.000000 0.000000 @�'�. sscanf() read 1 items
预期输出:
readed line is: 3888914775 Itzel Gardner 21.000000 26.000000 Iran Tehran. sscanf() read 6 items
另一个编辑:
问题要求是添加制表符,所以如果输入中有空格,它应该返回这个输入是不正确的,不应该读取它。这是我添加制表符的主要原因,所以它只能读取其中有制表符的输入,所以例如,如果id和name之间的输入只有1个空格,它就不应该读取。很抱歉混淆了所有
因此,在[100]行="3888914775 Itzel Gardner 21 26 Iran Tehran";
输入每个之间的分隔输入只能是制表符,没有其他内容(不能是一个空格或两个..(
正确的输入示例:
line[100]="388891477tItzeltGardnert21t6tIrantTehran";
在我看来,您的代码有一些问题。
首先,%*[t]
说明符具有干扰性,不应该是必需的。sscanf
中的说明符之间的空格将导致所有空白都被消耗掉。
其次,您的ID值可能会溢出long int
,因此您可能需要将long long
与%lld
说明符一起使用。
最后,对于空格还是制表符分隔字段,似乎存在一些混淆。空格是所有字符串字段的有效值,但也可以在字段之间指定。你的评论提到了标签,但我在你的line
字符串中看不到任何标签。如果使用制表符来分隔字段,效果会更好,因为制表符不是说明符集的一部分。
这是我对你的代码的更新,更正了以上所有内容:
#include <stdio.h>
int main() {
long long id;
float grade,age;
char name[40],city[40],country[40],line[100]="3888914775tItzel Gardnert21t26tIrantTehran";
int read_items = sscanf(line,"%lld %[a-zA-Z -] %f %f %[a-zA-Z -] %[a-zA-Z -]",
&id,name,&age,&grade,country,city);
printf("readed line is: %lld %s %f %f %s %s. sscanf() read %d itemsn",id,name,grade,age,country,city,read_items);
}
输出:
readed line is: 3888914775 Itzel Gardner 26.000000 21.000000 Iran Tehran. sscanf() read 6 items
int main() {
long int id;
float grade,age;
char name[40],city[40],country[40],line[100]="3888914775 Itzel Gardner 21 26 Iran Tehran";
int read_items = sscanf(line,"%ld %[a-zA-Z- ] %f %f %[a-zA-Z-] %[a-zA-Z-]",
&id,name,&age,&grade,country,city);
printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d itemsn",id,name,grade,age,country,city,read_items);
}
从sscanf中删除%*[t]
时,您的程序将正常工作。此外,您也不想将数据类型从float更改为int。希望这会有所帮助:(
使用字符串文字串联来帮助清楚地解决此问题。
若要扫描而不保存't'
而仅保存1,请使用"%*1[t]"
。
安全扫描-保存字符串时使用宽度限制。例如"%39[^t]"
未测试代码:
#define FTAB "%*1[t]"
#define FID FTAB "%ld"
#define FTXT FTAB "%39[^t]"
#define FNUM FTAB "%f"
long int id;
float grade,age;
char name[40],city[40],country[40];
char line[100]="388891477tItzeltGardnert21t6tIrantTehran";
int read_items = sscanf(line, FID FTXT FNUM FNUM FTXT FTXT,
&id, name, &age, &grade, country, city);
printf("read %d itemsn", read_items);
if (read_itmes == 6) {
printf("readed line is: %ld %s %f %f %s %sn",
id, name, grade, age, country, city);
}
- 你在用空格写你的名字。因此,它将被视为下一个输入,并被接受为代码中的下一个数据类型:
在字符数组行中,Itzel Gardner这是每个字符之间有空格另外
- 您不需要给[A-Z-A-Z]将字符串存储到char数组中,只需使用%s即可
在sscanf中,您应该使用%s而不是[A-Z-A-Z]。-您不需要在sscanf函数中输入"\t"。
此代码有一个解决方案
int main()
{
long int id;
float grade,age;
char name[40],city[40],country[40],line[100]="3888914775 Itzel_Gardean 21 26 Iran Tehran";
int read_items = sscanf(line,"%ld %s %f %f %s %s",&id,name,&age,&grade,country,city);
printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d itemsn",id,name,grade,age,country,city,read_items);
}