gpt4 book ai didi

c - fscanf 检索数字信息的模式

转载 作者:太空宇宙 更新时间:2023-11-04 02:34:35 25 4
gpt4 key购买 nike

我正在尝试创建一种算法来读取具有这种形状的文件:

+6.590472E-01;+2.771043E+07;+
-5.003500E-02;-8.679890E-02;-

如您所见,它包含三列。其中两个是数字,最后一个是信号。

我已经将行作为 char[30] 并用分号分隔列。

现在,让我们假设数字“+6.590472E-01”。我需要将它分成四个信息:符号(+-),点前的数字(0 到 9,在本例中为 6),之间的数字点和指数 (590472),最后是指数 (-01)。

如何使用 fscanf 检索这些信息?我必须使用哪种模式?

最佳答案

假设声明如下:

 char s1[2], s2[2], s3[2];
char int1[21], int2[21], frac1[21], frac2[21];
char exp1[6], exp2[6];

并假设您阅读了带有 fgets() 的行或者 getline()成一个字符串变量string,然后你可以使用sscanf()来一次性解析字符串,如下所示:

if (sscanf(string, "%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];%1[-+]",
s1, int1, frac1, exp1, s2, int2, frac2, exp2, s3) != 9)
…something went wrong — at least we can analyze the string…
else
…got the information…

请注意在格式字符串中使用了 20 但在变量声明中使用了 21;这个差一个是很久以前(大约 1979 年)在标准 I/O 库中做出的设计决定,远早于标准。 %*[eE] 允许 eE 作为指数标记,并禁止赋值。请注意,指数项将允许 E9-8+7 作为指数,并且不会坚持符号;除非您分两部分收集指数,否则没有简单的解决方法。

您也不能简单地判断扫描完成的位置。您可以在末尾添加 %n 转换规范,并将 &n 作为额外参数传递(使用 int n; 作为变量定义) . %n 不计算在内,所以条件不变。然后,您可以检查 buffer[n] 以查看转换停止的位置 — 是换行符、字符串结尾还是伪造的东西?

请注意,由于格式字符串自始至终都使用 %[…] 扫描集,因此不会消耗任何空格——输入中的任何空格都会触发错误。

这需要对 sscanf() 的规范有相当全面的了解.你可能需要在接下来的一个月左右的时间里读六六遍才能开始掌握它,然后在接下来的一年里再读六遍,之后你可能会明白每年修订一次 — 它是一个复杂的函数(scanf() 函数族是标准 C 中最复杂的函数之一)。


测试代码

#include <stdio.h>

int main(void)
{
char string[] = "+6.590472E-01;+2.771043E+07;+\n";
char s1[2], s2[2], s3[2];
char int1[21], int2[21], frac1[21], frac2[21], exp1[6], exp2[6];
int n;
int rc;

if ((rc = sscanf(string, "%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];%1[-+]%n",
s1, int1, frac1, exp1, s2, int2, frac2, exp2, s3, &n)) == 9)
{
printf("[%s][%s].[%s]E[%s]\n", s1, int1, frac1, exp1);
printf("[%s][%s].[%s]E[%s]\n", s2, int2, frac2, exp2);
printf("[%s] %d (%d = '%c')\n", s3, n, string[n], string[n]);
}
else
printf("Oops (rc = %d)!\n", rc);
return 0;
}

输出:

[+][6].[590472]E[-01]
[+][2].[771043]E[+07]
[+] 29 (10 = '
')

chqrlie 所述在comment ,编写 if 语句的更好方式可能更像是:

    if ((rc = sscanf(string, "%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];"
"%1[-+]%20[0-9].%20[0-9]%*[eE]%5[-+0-9];" "%1[-+]%n",
s1, int1, frac1, exp1,
s2, int2, frac2, exp2, s3, &n)) == 9)

这里使用相邻字符串连接来强调格式字符串的前两段是相同的,然后或多或少地拆分变量来匹配。有许多类似的布局也可以使用。

关于c - fscanf 检索数字信息的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39187513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com