0
#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);
}

上面的代码不适用于 '\t',为什么?它适用于此 我正在使用vc6.0

不工作

char *tokenstring = "first\t25.5\tsecond\t15";



   result = sscanf(tokenstring, "%[^'\t'],%[^'\t'],%[^'\t'],%s", o, s, t, f);
4

2 回答 2

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]不匹配空字符串的模式——如果输入中的下一个字符是 a ,(或\t在第二种情况下),scanf 将简单地返回而不匹配任何东西(或任何以下模式),而不是存储一个空字符串。

此外,如果您的任何字符串对于数组来说太长,您将溢出并崩溃(或更糟)。因此,每当您在缓冲区中使用 scanf%s%[模式时,您应该始终指定缓冲区大小:

sscanf(tokenstring, "%9[^,],%9[^,],%9[^,],%9s", o, s, t, f);

现在,当输入太长时,sscanf调用将只匹配字段的前 9 个字符,并返回尚未读取的字段的其余部分,而不是崩溃或损坏东西。

于 2014-04-18T17:34:55.107 回答
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();
}
于 2014-04-18T17:34:26.083 回答