user-0 提问: 关于sscanf使用的一些疑惑

回复:
user: user-1
content: 引用 4 楼 不闻窗外事 的回复:那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);   需要，否则得到的数据就不对，也就是输入 5=abc 或者  5 = abc 可以参考以下关于空白符的描述部分 http://c.biancheng.net/view/415.html https://blog.csdn.net/21aspnet/article/details/174326  关于char buf[] = "123 = abc"; 包含空格时输入不对的问题，原因很简单，对于输入数据来说，扫描器是以空白符来分割信息的，也就是遇到空白符时读入一个数据进来，所以"123 = abc"被当作3个数据读入（”123“， ”=“， ”abc“），而sscanf每次只会读入一个数据，即只读入“123”，然后用“123”去匹配格式，结果只有第一个数据符合（“123”后面的数据算空字符串，即"%[^= \t]=%s"前半部符合，后半部为空） 你可以查看sscanf读入成功的数据就知道了 char buf[] = "123 = abc"; char key[256]; char value[256]; int n = sscanf(buf, "%[^= \t]=%s", key, value); //读入了几个数据？ printf("key=[%s] value[%s]\n", key, value); printf("%d\n", n); //确认读入几个数据  至于格式不匹配为啥还会读入数据?输入格式没有规定完全匹配才会读入数据，而是匹配一个读入一个，如果匹配出错则后面就不会继续读入 比如 int a=0,b=0; char c='?'; scanf("%d%d%c", &a,&b,&c); //程序运行后输入：1 2a会车，看看什么结果，再运行一次输入：1 ab回车，看看什么结果 printf("%d,%d,%c\n", a, b, c);

user: user-0
content: 引用 3 楼 自信男孩 的回复:对于多个格式的文件输入scanf,是用空格来区分开来的。比如  scanf("%d%s", &num, str); 输入两个类型数据%d和%s。只要中间加上至少一个空格，就可以分开两个输入。 那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);

user: user-2
content: 对于多个格式的文件输入scanf,是用空格来区分开来的。比如  scanf("%d%s", &num, str); 输入两个类型数据%d和%s。只要中间加上至少一个空格，就可以分开两个输入。

user: user-0
content: 引用 1 楼 自信男孩 的回复:scanf/printf sscanf/fprintf snprintf这些都是格式化的输入输出，因此需要严格按照格式来～ 大哥，我问得就是为什么sscanf在匹配是会忽略空格，严格按照格式，那岂不是就不能忽略了？？？

user: user-2
content: scanf/printf sscanf/fprintf snprintf这些都是格式化的输入输出，因此需要严格按照格式来～

user: user-1
content: 引用 14 楼 不闻窗外事 的回复:[quote=引用 13 楼 qybao 的回复:] 你的意思就是说scanf这种它的匹配模式中，如果有空格，可以匹配输入的多个空格，也可以直接略过空格，匹配下一部分？？？ 理论上是这样的，除非还有其他特殊的输入格式 相当于"%d %d"格式可以匹配 "数字空格*数字" 这样的输入（空格*表示中间有任意个空格）

user: user-0
content: 引用 13 楼 qybao 的回复:[quote=引用 11 楼 不闻窗外事 的回复: 大哥，你说的这些我都知道，我想知道的不是略去一个还是多个空格，也不是你举得两个例子，你能看看你举得两个例子跟我举得例子的区别吗？？？你的第二个例子如果“1=abc”没有空格，也可以，你不信试试。你说过滤一个或者多个空格，但是“1=abc”这种一个空格都没有啊，为什么也可以得到正确的结果，你说的是多个空格的情况，我问得是“1=abc”没有空格的情况。关键按你说的没有空格是不行的，但是实际上是可以的，这才是问题所在  你没理解我说的。“1=abc”这种一个空格都没有也可以，是因为格式化字符串带空格就会略过输入数据的空格继续读入下一个非空格开始的数据，所以你的输入数据没空格也可以的呀，就是没有略过任何空格，直接读取到下一个非空格数据而已。[/quote] 你的意思就是说scanf这种它的匹配模式中，如果有空格，可以匹配输入的多个空格，也可以直接略过空格，匹配下一部分？？？

user: user-1
content: [quote=引用 11 楼 不闻窗外事 的回复: 大哥，你说的这些我都知道，我想知道的不是略去一个还是多个空格，也不是你举得两个例子，你能看看你举得两个例子跟我举得例子的区别吗？？？你的第二个例子如果“1=abc”没有空格，也可以，你不信试试。你说过滤一个或者多个空格，但是“1=abc”这种一个空格都没有啊，为什么也可以得到正确的结果，你说的是多个空格的情况，我问得是“1=abc”没有空格的情况。关键按你说的没有空格是不行的，但是实际上是可以的，这才是问题所在[/quote]  你没理解我说的。“1=abc”这种一个空格都没有也可以，是因为格式化字符串带空格就会略过输入数据的空格继续读入下一个非空格开始的数据，所以你的输入数据没空格也可以的呀，就是没有略过任何空格，直接读取到下一个非空格数据而已。

user: user-0
content: 引用 10 楼 qybao 的回复:[quote=引用 7 楼 不闻窗外事 的回复:] scanf("%d = %s", &num, str);就拿这个来说吧，为什么我输入“123 = hello”可以，输入“123=hello”也是一样的，为什么明明是"%d = %s"，却可以忽略空格，不输入空格。最后的结果都是num=123，str=hello，返回值都是2  我给你发的那两个链接你点进去看了吗？里面提到的是格式符字符串中带空格的情况。至于buf带空格的问题，只是告诉你原因所在，不是让你把重点转到buf带空格。所以你可以好看看链接对格式化字符串中带空格的处理的描述。  以下摘自链接中的说明 （B）         空白字符 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。  所以，如果格式化字符串如果没有空格，那么输入的数据也不能带空格；如果格式化字符串带空格，那么输入数据可以在两个匹配格式之间加任意空格（因为空格回被略去，直接匹配下一个非空格字符开始的数据）  比如 scanf("%d=%s", &num, str); 输入"1 = abc"会出错，因为格式化字符串没有空格，所以输入数据带空格就和格式化字符串不匹配 scanf("%d = %s", &num, str); 输入“1     =          abc”也能正确读入数据，因为格式化字符串带空格，所以输入数据的空格被略过，读入正确  [/quote] 我把例子写到这里， int main(int argc, char *argv[]) { 	int num; 	char str[128]; 	int i = scanf("%d = %s", &num, str); 	printf("i = %d num=%d str=[%s]\n", i, num, str);     return 0; }  结果： 123=abc i = 2 num=123 str=[abc]

user: user-0
content: 引用 10 楼 qybao 的回复:[quote=引用 7 楼 不闻窗外事 的回复:] scanf("%d = %s", &num, str);就拿这个来说吧，为什么我输入“123 = hello”可以，输入“123=hello”也是一样的，为什么明明是"%d = %s"，却可以忽略空格，不输入空格。最后的结果都是num=123，str=hello，返回值都是2  我给你发的那两个链接你点进去看了吗？里面提到的是格式符字符串中带空格的情况。至于buf带空格的问题，只是告诉你原因所在，不是让你把重点转到buf带空格。所以你可以好看看链接对格式化字符串中带空格的处理的描述。  以下摘自链接中的说明 （B）         空白字符 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。  所以，如果格式化字符串如果没有空格，那么输入的数据也不能带空格；如果格式化字符串带空格，那么输入数据可以在两个匹配格式之间加任意空格（因为空格回被略去，直接匹配下一个非空格字符开始的数据）  比如 scanf("%d=%s", &num, str); 输入"1 = abc"会出错，因为格式化字符串没有空格，所以输入数据带空格就和格式化字符串不匹配 scanf("%d = %s", &num, str); 输入“1     =          abc”也能正确读入数据，因为格式化字符串带空格，所以输入数据的空格被略过，读入正确  [/quote] 大哥，你说的这些我都知道，我想知道的不是略去一个还是多个空格，也不是你举得两个例子，你能看看你举得两个例子跟我举得例子的区别吗？？？你的第二个例子如果“1=abc”没有空格，也可以，你不信试试。你说过滤一个或者多个空格，但是“1=abc”这种一个空格都没有啊，为什么也可以得到正确的结果，你说的是多个空格的情况，我问得是“1=abc”没有空格的情况。关键按你说的没有空格是不行的，但是实际上是可以的，这才是问题所在

user: user-1
content: 引用 7 楼 不闻窗外事 的回复:scanf("%d = %s", &num, str);就拿这个来说吧，为什么我输入“123 = hello”可以，输入“123=hello”也是一样的，为什么明明是"%d = %s"，却可以忽略空格，不输入空格。最后的结果都是num=123，str=hello，返回值都是2  我给你发的那两个链接你点进去看了吗？里面提到的是格式符字符串中带空格的情况。至于buf带空格的问题，只是告诉你原因所在，不是让你把重点转到buf带空格。所以你可以好看看链接对格式化字符串中带空格的处理的描述。  以下摘自链接中的说明 （B）         空白字符 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。  所以，如果格式化字符串如果没有空格，那么输入的数据也不能带空格；如果格式化字符串带空格，那么输入数据可以在两个匹配格式之间加任意空格（因为空格回被略去，直接匹配下一个非空格字符开始的数据）  比如 scanf("%d=%s", &num, str); 输入"1 = abc"会出错，因为格式化字符串没有空格，所以输入数据带空格就和格式化字符串不匹配 scanf("%d = %s", &num, str); 输入“1     =          abc”也能正确读入数据，因为格式化字符串带空格，所以输入数据的空格被略过，读入正确

user: user-0
content: 引用 8 楼 自信男孩 的回复:[quote=引用 4 楼 不闻窗外事 的回复:][quote=引用 3 楼 自信男孩 的回复:]对于多个格式的文件输入scanf,是用空格来区分开来的。比如  scanf("%d%s", &num, str); 输入两个类型数据%d和%s。只要中间加上至少一个空格，就可以分开两个输入。 那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);[/quote] 需要的。  空格是区分两个输入的或者多个输入[/quote] scanf("%d = %s", &num, str);就拿这个来说吧，为什么我输入“123 = hello”可以，输入“123=hello”也是一样的，为什么明明是"%d = %s"，却可以忽略空格，不输入空格。最后的结果都是num=123，str=hello，返回值都是2  “123=hello”并没有空格啊，一样匹配“%d = %s”

user: user-2
content: 引用 4 楼 不闻窗外事 的回复:[quote=引用 3 楼 自信男孩 的回复:]对于多个格式的文件输入scanf,是用空格来区分开来的。比如  scanf("%d%s", &num, str); 输入两个类型数据%d和%s。只要中间加上至少一个空格，就可以分开两个输入。 那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);[/quote] 需要的。  空格是区分两个输入的或者多个输入

user: user-0
content: 引用 5 楼 qybao 的回复:[quote=引用 4 楼 不闻窗外事 的回复:] 那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);   需要，否则得到的数据就不对，也就是输入 5=abc 或者  5 = abc 可以参考以下关于空白符的描述部分 http://c.biancheng.net/view/415.html https://blog.csdn.net/21aspnet/article/details/174326  关于char buf[] = "123 = abc"; 包含空格时输入不对的问题，原因很简单，对于输入数据来说，扫描器是以空白符来分割信息的，也就是遇到空白符时读入一个数据进来，所以"123 = abc"被当作3个数据读入（”123“， ”=“， ”abc“），而sscanf每次只会读入一个数据，即只读入“123”，然后用“123”去匹配格式，结果只有第一个数据符合（“123”后面的数据算空字符串，即"%[^= \t]=%s"前半部符合，后半部为空） 你可以查看sscanf读入成功的数据就知道了 char buf[] = "123 = abc"; char key[256]; char value[256]; int n = sscanf(buf, "%[^= \t]=%s", key, value); //读入了几个数据？ printf("key=[%s] value[%s]\n", key, value); printf("%d\n", n); //确认读入几个数据  至于格式不匹配为啥还会读入数据?输入格式没有规定完全匹配才会读入数据，而是匹配一个读入一个，如果匹配出错则后面就不会继续读入 比如 int a=0,b=0; char c='?'; scanf("%d%d%c", &a,&b,&c); //程序运行后输入：1 2a会车，看看什么结果，再运行一次输入：1 ab回车，看看什么结果 printf("%d,%d,%c\n", a, b, c);    [/quote] scanf("%d = %s", &num, str);就拿这个来说吧，为什么我输入“123 = hello”可以，输入“123=hello”也是一样的，为什么明明是"%d = %s"，却可以忽略空格，不输入空格。最后的结果都是num=123，str=hello，返回值都是2

user: user-0
content: 引用 5 楼 qybao 的回复:[quote=引用 4 楼 不闻窗外事 的回复:] 那如果是这种呢？？空格需要匹配吗？？？ scanf("%d = %s", &num, str);   需要，否则得到的数据就不对，也就是输入 5=abc 或者  5 = abc 可以参考以下关于空白符的描述部分 http://c.biancheng.net/view/415.html https://blog.csdn.net/21aspnet/article/details/174326  关于char buf[] = "123 = abc"; 包含空格时输入不对的问题，原因很简单，对于输入数据来说，扫描器是以空白符来分割信息的，也就是遇到空白符时读入一个数据进来，所以"123 = abc"被当作3个数据读入（”123“， ”=“， ”abc“），而sscanf每次只会读入一个数据，即只读入“123”，然后用“123”去匹配格式，结果只有第一个数据符合（“123”后面的数据算空字符串，即"%[^= \t]=%s"前半部符合，后半部为空） 你可以查看sscanf读入成功的数据就知道了 char buf[] = "123 = abc"; char key[256]; char value[256]; int n = sscanf(buf, "%[^= \t]=%s", key, value); //读入了几个数据？ printf("key=[%s] value[%s]\n", key, value); printf("%d\n", n); //确认读入几个数据  至于格式不匹配为啥还会读入数据?输入格式没有规定完全匹配才会读入数据，而是匹配一个读入一个，如果匹配出错则后面就不会继续读入 比如 int a=0,b=0; char c='?'; scanf("%d%d%c", &a,&b,&c); //程序运行后输入：1 2a会车，看看什么结果，再运行一次输入：1 ab回车，看看什么结果 printf("%d,%d,%c\n", a, b, c);  [/quote]  谢谢回复，但是我在意的空格不是输入时的空格，而是sscanf中的空格，我的意思是sscanf(buf, "%[^= \t] = %s", key, value); 中引号内部的空格，而不是buf中的空格，为什么引号内部的空格在buf中没有被匹配，仍然会继续匹配，例如char buf[] = "123=abc";没有空格，但是"%[^= \t]"匹配完123之后，在sscanf的引号内部应该匹配空格了，但是buf中下一个字符是等号，在这种情况下，sscanf引号中等号前的那个空格被忽略了，继续用引号中的等号匹配buf中的等号。