- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有以下问题: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 个单独命名的变量是一个可怕的想法;使用它们的代码会很糟糕。
请注意,扫描集转换规范将字符串的最大长度限制为比 jokeri
和 paiva
数组元素的大小短一个。
您可能想知道为什么代码在 &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/
使用登录后,我想吐出用户名。 但是,当我尝试单击登录按钮时, 它给了我力量。 我看着logcat,但是什么也没显示。 这种编码是在说。 它将根据我在登录屏幕中输入的名称来烘烤用户名。 不会有任何密码。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我是一名优秀的程序员,十分优秀!