#include <math.h>
#include <stdio.h>
#include <stdlib.h>
char *tokenstring = "first,25.5,second,15";
int result, i;
double fp;
char o[10], f[10], s[10], t[10];
void main()
{
result = sscanf(tokenstring, "%[^','],%[^','],%[^','],%s", o, s, t, f);
printf("%s\n %s\n %s\n %s\n", o, s, t, f);
fp = atof(s);
i = atoi(f);
printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}
以上代码不适用于&#39; \ t&#39;,为什么?它适用于this 我使用的是vc6.0
无效
char *tokenstring = "first\t25.5\tsecond\t15";
result = sscanf(tokenstring, "%[^'\t'],%[^'\t'],%[^'\t'],%s", o, s, t, f);
答案 0 :(得分:3)
查看您的格式匹配:
"%[^'\t'],%[^'\t']
^ ^ ^
\ | \- match a literal comma
\ |
\---+- match a sequence not containing tab or ' (single quote), up to the next
tab or single quite.
所以第一个%[..]
匹配所有内容,不包括输入中的第一个标签,然后它尝试匹配与标签不匹配的逗号,因此失败。
最简单的解决方法是用空格替换字符串中的逗号,这将跳过空格(包括制表符)。使用制表符会做同样的事情,但会让人误以为你试图匹配制表符而不是跳过空格:
sscanf(tokenstring, "%[^\t] %[^\t] %[^\t]%s", o, s, t, f);
请注意,您可能也不希望在比赛中特别处理'
个字符,除非您希望它们失败。
现在,如果您只想使用分隔符选项卡(而不仅仅是任何空格),则需要使用选项卡模式:
sscanf(tokenstring, "%[^\t]%*1[\t\]%[^\t]%*1[\t]%[^\t]%s", o, s, t, f);
模式%*1[\t]
将完全匹配输入中的单个选项卡,而不是将其存储在任何位置。
这导致您可能已经注意到第一个(基于逗号的)scanf的另一个问题 - 像%[^,]
或%[^\t]
这样的模式将不匹配空字符串 - 如果下一个字符在输入是,
(或第二种情况下为\t
),scanf将返回而不匹配任何内容(或以下任何模式),而不是存储空字符串。
此外,如果您的任何字符串对于数组而言太长,您将溢出并崩溃(或更糟)。因此,无论何时将scanf %s
或%[
模式用于缓冲区,都应始终指定缓冲区大小:
sscanf(tokenstring, "%9[^,],%9[^,],%9[^,],%9s", o, s, t, f);
现在,当输入太长时,sscanf
调用将只匹配字段的前9个字符,而不是崩溃或损坏,而是返回该字段的其余部分尚未被读取。
答案 1 :(得分:2)
当您使用逗号分隔字段时,您必须在格式字符串中添加,
以便跳过它。同样适用于\t
。
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
void test1()
{
char *tokenstring = "first,25.5,second,15";
int result, i;
double fp;
char o[10], f[10], s[10], t[10];
// -----------------------------------------------------------
// make sure you add a , between the string format specifiers
// -----------------------------------------------------------
result = sscanf(tokenstring, "%[^,],%[^,],%[^,],%s", o, s, t, f);
printf("%s\n %s\n %s\n %s\n", o, s, t, f);
fp = atof(s);
i = atoi(f);
printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}
void test2()
{
char *tokenstring = "first\t25.5\tsecond\t15";
int result, i;
double fp;
char o[10], f[10], s[10], t[10];
// -----------------------------------------------------------
// make sure you add a \t between the string format specifiers
// -----------------------------------------------------------
result = sscanf(tokenstring, "%[^\t]\t%[^\t]\t%[^\t]\t%s", o, s, t, f);
printf("%s\n %s\n %s\n %s\n", o, s, t, f);
fp = atof(s);
i = atoi(f);
printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}
void main()
{
test1();
test2();
}