简体   繁体   English

sscanf()双显示零

[英]sscanf() double showing zeros

I'm having troubles with sscanf() function to read doubles. 我在使用sscanf()函数读取双打时遇到麻烦。 I have a comma separated text file like this: 我有一个逗号分隔的文本文件,如下所示:

ABC,DEF,0.465798,0.754314
GHI,JKL,0.784613,0.135264
MNO,OPQ,0.489614,0.745812
etc.

So first I get the line with fgets() and then I use sscanf() to get the two string and two double variables. 所以首先我用fgets()获取行,然后使用sscanf()获取两个字符串和两个双变量。

fgets(buffer, 28, file);
sscanf(buffer, "%4[^,],%4[^,],%lf[^,],%lf[^\n]", string1, string2, &double1, &double2);

printf("%s %s %f %f\n", string1, string2, double1, double2);

But the output is: 但输出是:

ABC DEF 0.465798 0.000000
GHI JKL 0.784613 0.000000
MNO OPQ 0.489614 0.000000

So somehow it doesn't scan the last float. 所以它不会扫描最后一个浮点数。 I've tried %lf[^ \\t\\n\\r\\v\\f,] and just %lf but it still doesn't work. 我已经尝试了%lf[^ \\t\\n\\r\\v\\f,]%lf但它仍然无效。

Unless your variables double1 and double2 are pointers, you will get undefined behavior. 除非您的变量double1double2是指针,否则您将获得未定义的行为。

You need to use the address-of operator & to get a pointer to those variables: 您需要使用address-of运算符&来获取指向这些变量的指针:

sscanf(buffer, "%3s,%3s,%lf,%lf", string1, string2, &double1, &double2);

Change 更改

"%4[^,],%4[^,],%lf[^,],%lf[^\n]"

To

int result;
result = sscanf(buffer, "%4[^,],%4[^,],%lf,%lf", string1, string2, &double1, &double2);
if (result != 4) // handle error

Notice the & on double1 and double2 - likley a typo. 请注意& on double1double2 - double2是一个错字。

Also strongly recommend to check that the result is 4. Not checking the sscanf() result is really core to this question. 强烈建议检查结果是4.不检查sscanf()结果是这个问题的核心。 The "zeros" printed out are the result of double2 not having been scanned and retained its previous value which could have been anything. 打印出的“零”是double2未扫描并保留其先前值的结果,可能是任何东西。 Had the sscanf() result been checked it would have reported 3, showing the problem was between scanning double1 and double2 . 如果检查了sscanf()结果,它会报告3,显示问题是在扫描double1double2之间。 But in the larger scene, it is good practice to verify all the expected values were scanned before going on. 但是在较大的场景中,最好在继续之前验证扫描所有预期值。

sscanf(buffer, "%4[^,],%4[^,],%lf[^,],%lf[^\n]", string1, string2, double1, double2);

should be 应该

sscanf(buffer, "%3s,%3s,%lf,%lf", string1, string2, &double1, &double2);

Note & (address of) for doubles 双打的注释& (地址)

The reason that your code didn't work is because: 您的代码无效的原因是:

sscanf(buffer, "%4[^,],%4[^,],%lf[^,],%lf[^\n]", string1, string2, &double1, &double2);

%[...] and %[^...] are actually conversion types, like %d , %x , and they match/don't match sequence of listed characters, ending with ] . %[...]%[^...]实际上是转换类型,例如%d%x ,它们匹配/不匹配列出的字符序列,以]结尾。 Notice that you don't have to provide %s , even though you're parsing string. 请注意,即使您正在解析字符串,也不必提供%s

Your problem was that you combined two type of conversion types, %lf and [^...] , scanf actually sees the later part as the string to match, so for instance following code would successfully parse the string: 你的问题是你结合了两种类型的转换类型, %lf[^...] ,scanf实际上将后面的部分视为要匹配的字符串,因此例如以下代码将成功解析字符串:

char *b = "ABC,DEF,0.465798[^,],0.754314[^\n]\n";
sscanf(b, "%4[^,],%4[^,],%lf[^,],%lf[^\n]", string1, string2, &double1, &double2);

The easiest solution is to leave [^,] part (chux's solution): 最简单的解决方案是留下[^,]部分(chux的解决方案):

sscanf(b, "%4[^,],%4[^,],%lf,%lf", string1, string2, &double1, &double2);

Or use field width (Joachim Pileborg, and David RF's solution): 或者使用场宽(Joachim Pileborg和David RF的解决方案):

sscanf(buffer, "%3s,%3s,%lf,%lf", string1, string2, &double1, &double2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM