gpt4 book ai didi

c - Sscanf 没有返回我想要的

转载 作者:太空宇宙 更新时间:2023-11-04 07:16:58 26 4
gpt4 key购买 nike

我有以下问题:sscanf 没有按我想要的方式返回。这是 sscanf:

sscanf(naru,
"%s[^;]%s[^;]%s[^;]%s[^;]%f[^';']%f[^';']%[^;]%[^;]%[^;]%[^;]"
"%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]"
"%[^;]%[^;]%[^;]%[^;]%[^;]%[^;]",
&jokeri, &paiva1, &keskilampo1, &minlampo1, &maxlampo1,
&paiva2, &keskilampo2, &minlampo2, &maxlampo2, &paiva3,
&keskilampo3, &minlampo3, &maxlampo3, &paiva4, &keskilampo4,
&minlampo4, &maxlampo4, &paiva5, &keskilampo5, &minlampo5,
&maxlampo5, &paiva6, &keskilampo6, &minlampo6, &maxlampo6,
&paiva7, &keskilampo7, &minlampo7, &maxlampo7);

它正在扫描的字符串:

const char *str = "city;"
"2014-04-14;7.61;4.76;7.61;"
"2014-04-15;5.7;5.26;6.63;"
"2014-04-16;4.84;2.49;5.26;"
"2014-04-17;2.13;1.22;3.45;"
"2014-04-18;3;2.15;3.01;"
"2014-04-19;7.28;3.82;7.28;"
"2014-04-20;10.62;5.5;10.62;";

所有变量都存储为 char paiva1[22] 等;但是,sscanf 没有正确存储城市以外的任何内容。我一直试图在 ; 处停止每个变量。任何帮助如何让它正确存储日期等的帮助将不胜感激。

或者如果有更聪明的方法来做到这一点,我愿意接受建议。

最佳答案

有多个问题,但是BLUEPIXY命中第一个 — 扫描集符号不遵循 %s

格式的第一行是:

"%s[^;]%s[^;]%s[^;]%s[^;]%f[^';']%f[^';']%[^;]%[^;]%[^;]%[^;]"

就目前而言,它会查找一个空格分隔的单词,然后是 [^;](自相矛盾,字符串后面的字符是空格或字符串结尾)。

第一个修正是正确使用扫描集:

"%[^;]%[^;]%[^;]%[^;]%f[^';']%f[^';']%[^;]%[^;]%[^;]%[^;]"

现在你遇到一个问题,第一个 %[^;] 扫描所有内容直到字符串末尾或第一个分号,而第二个 %[;] 什么也没有留下> 匹配。

"%[^;]; %[^;]; %[^;]; %[^;]; %f[^';']%f[^';']%[^;]%[^;]%[^;]%[^;]"

这将查找一个字符串直到一个分号,然后是分号,然后是可选的空格,然后重复三个项目。除了加一个长度来限制字符串的大小,防止溢出,这些都可以。 %f 没问题。以下 Material 再次查找奇数字符序列。

但是看数据,好像是一个城市,然后是七组‘一个日期加三个数字’。

你最好使用一个结构数组(如果你已经使用过那些),或者一组 4 个并行数组和一个循环:

char jokeri[30];
char paiva[7][30];
float keskilampo[7];
float minlampo[7];
float maxlampo[7];

int eoc; // End of conversion
int offset = 0;
char sep;
if (fscanf(str + offset, "%29[^;]%c%n", jokeri, &sep, &eoc) != 2 || sep != ';')
...report error...
offset += eoc;

for (int i = 0; i < 7; i++)
{
if (fscanf(str + offset, "%29[^;];%f;%f;%f%c%n", paiva[i],
&keskilampo[i], &minlampo[i], &maxlampo[i], &sep, &eoc) != 5 ||
sep != ';')
...report error...
offset += eoc;
}

另见 How to use sscanf() in loops .

现在您有了可以管理的数据。一组 29 个单独命名的变量是一个可怕的想法;使用它们的代码会很糟糕。

请注意,扫描集转换规范将字符串的最大长度限制为比 jokeripaiva 数组元素的大小短一个。


您可能想知道为什么代码在 &eoc 之前使用 %c%n&sep。这是有原因的,但它很微妙。假设sscanf()格式字符串为:

"%29[^;];%f;%f;%f;%n"

此外,假设数据中存在问题,即第三个数字后的分号丢失。对 sscanf() 的调用将报告它进行了 4 次成功的转换,但它没有将 %n 算作一个赋值,所以你不能说 sscanf() 没有找到分号,因此根本没有设置 &eoc;该值是以前调用 sscanf() 时留下的,或者只是未初始化。通过使用 %c 将值扫描到 sep 中,我们在成功时返回 5,并且我们可以确定 %n 是成功的也。该代码检查 sep 中的值实际上是分号而不是其他内容。

您可能需要考虑在分号之前和 %c 之前留一个空格。他们将允许转换一些其他数据字符串,否则这些字符串将无法匹配。格式字符串中的空格(在扫描集之外)指示可能出现可选空格的位置。

关于c - Sscanf 没有返回我想要的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23838319/

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