所以我的文本文件看起来与此类似
1. First 1.1
2. Second 2.2
基本上是整数,字符串,然后是浮点数。
理论上使用sscanf()
和fgets()
,我应该能够扫描这个(我必须以这种格式进行)但是只有得到整数才能有人帮我指出我做错了什么?
while(!feof(foo))
{
fgets(name, sizeof(name) - 1, foo);
sscanf(name,"%d%c%f", &intarray[i], &chararray[i], &floatarray[i]);
i++;
}
其中intarray
,chararray
和floatarray
是1D数组,而i
是int
初始化为0.
答案 0 :(得分:0)
您需要sscanf
中的空格。
sscanf(name,"%d %s %f", &intarray[i], &chararray[i], &floatarray[i]);
没有空白,它就会期待所有东西都被混合在一起。
请注意,scanf
中的单个空格实际上会匹配多个空格字符(例如,两个空格,或多个空格和制表符)。
答案 1 :(得分:0)
对于字符串不是%s,否则它只会读取带有%c的字符,然后浮点值可能会受到影响。 尝试“%d%s%f”
%s无效,因为它可能会读取浮点值本身。据我所知,%c读取一个字符。然后它搜索导致问题的空间。要扫描单词,您可以使用循环(以空格结束)。
答案 2 :(得分:0)
您需要将格式字符串更改为:
"%d %s %f"
这些空格是因为输入数据中有空格%s
,因为你想在那一点读取一个多字符串(%c
只读取一个字符);不要担心,因为%s
不会读过一个空格。当然,您需要确保目标缓冲区中有足够的空间来读取字符串。
如果您只想要第二个单词的第一个字符,请尝试:
"%d %c%s %f"
添加一个额外的(虚拟)缓冲区以接收您要丢弃的%s
解析的字符串。
答案 3 :(得分:0)
循环结构错误;您不应该使用feof()
,而必须始终检查fgets()
和sscanf()
的状态。此代码也避免了输入数组的溢出。
enum { MAX_ENTRIES = 10 };
int i;
int intarray[MAX_ENTRIES];
float floatarray[MAX_ENTRIES];
char chararray[MAX_ENTRIES][50];
for (i = 0; i < MAX_ENTRIES && fgets(name, sizeof(name), foo) != 0; i++)
{
if (sscanf(name,"%d. %49s %f", &intarray[i], chararray[i], &floatarray[i]) != 3)
...process format error...
}
请注意主要变化:
chararray
必须是2D数组才有意义。如果您使用%c
读取单个字符,则它将包含第一个数字后面的空格,并且后续转换规范(对于浮点值)将失败,因为字符串名称不是浮点值。&
前面的chararray[i]
。如果您真的在一维字符数组中读取单个字符而不是整个字符串,例如样本数据中的“第一个”或“第二个”,则需要它。sscanf()
,如果字符串中没有任何内容可以处理第一个转换规范(空字符串,所有空格),则只返回EOF;如果第一个非空格是字母或除+
或-
以外的标点字符等,则会返回0 如果你真的想要一个字符而不是名字,那么你必须安排阅读单词中的额外字符,可能使用:
if (sscanf(name,"%d %c%*s %f", &intarray[i], chararray[i], &floatarray[i]) != 3)
在%c
之前有一个空间是至关重要的;它将跳过输入中的空白区域,然后%c
将获取第一个非空白字符。 %*s
将读取更多字符,跳过任何空格(不会有任何空格),然后扫描一串字符直到下一个空白区域。 *
抑制了作业;扫描的数据不会存储在任何地方。
fgets()
加sscanf()
范例的一个主要优点是,当您报告格式错误时,您可以向用户报告导致问题的完整输入行。如果使用原始fscanf()
或scanf()
,则只能报告导致问题的第一个字符,通常直到行尾,然后才会编写代码来读取该数据。这是比较繁琐的(因此报告通常不是很谨慎),并且在报告试图小心的极少数情况下,可用信息对用户没有帮助。