1

所以我的文本文件看起来与此类似

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++;
}

其中intarraychararray和是floatarray一维数组,初始化为 0。 iint

4

3 回答 3

1

循环结构错误;您不应该那样使用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...
}

注意主要变化:

  1. 整数后面的点必须由格式字符串扫描。
  2. chararray必须是二维数组才有意义。如果您使用 读取单个字符%c,它将在第一个数字之后包含空格,并且后续转换规范(对于浮点值)将失败,因为字符串名称不是浮点值。
  3. 当它是二维数组时,不需要&前面的。chararray[i]如果您真的要读取一维字符数组中的单个字符,而不是示例数据中的“First”或“Second”等整个字符串,则需要使用它。
  4. 该测试检查三个值是否已成功转换。任何较小的值都表示存在问题。使用sscanf()时,只有在字符串中没有任何内容可供第一个转换规范处理时才会返回 EOF(空字符串,所有空格);如果第一个非空白是字母或除+or以外的标点符号等,则返回 0 -

如果您真的想要一个字符而不是名称,那么您必须安排阅读单词中的额外字符,也许使用:

    if (sscanf(name,"%d %c%*s %f", &intarray[i], chararray[i], &floatarray[i]) != 3)

在关键之前有一个空格%c;它将跳过输入中的空格,然后%c将拾取第一个非空白字符。将%*s读取更多字符,跳过任何空格(不会有任何空格),然后扫描一串字符直到下一个空格。*抑制分配;扫描的数据不会存储在任何地方。

fgets()plus范式的主要优点之一sscanf()是,当您报告格式错误时,您可以向用户报告导致问题的完整输入行。如果您使用 raw fscanf()or scanf(),您只能报告导致问题的第一个字符,通常直到行尾,并且仅当您编写代码来读取该数据时。它更复杂(因此报告通常不是很小心),并且在报告试图小心的极少数情况下,可用信息对用户没有帮助。

于 2013-05-30T05:52:25.293 回答
0

字符串不会是 %s ,否则它只会读取带有 %c 的字符,然后浮点值可能会受到影响。试试“%d %s %f”

%s 无济于事,因为它可能会读取浮点值本身。据我所知, %c 读取一个字符。然后它搜索导致问题的空间。要扫描单词,您可以使用循环(当然以空格结尾)。

于 2013-05-30T05:08:49.697 回答
0

您需要将格式字符串更改为:

"%d %s %f"

空格是因为您的输入数据中有空格,%s因为您想在该点读取多字符串(%c仅读取一个字符);不过不用担心,因为%s不会读取空格。当然,您需要确保目标缓冲区中有足够的空间来读取字符串。

如果您只想要第二个单词的第一个字符,请尝试:

"%d %c%s %f"

并添加一个额外的(虚拟)缓冲区来接收%s要丢弃的解析字符串。

于 2013-05-30T05:09:12.680 回答