用sscanf读取字符串的剩余部分
我正在尝试读取一个字符串,该字符串由一组数字后跟一个字符串组成,并包含一些其他基本文本。
换句话说,行的格式是这样的:
Stuff
天真地,我试过:
sscanf(str,"Stuff",&i1,&i2,&i3,&i4,str2);
但经过一些研究,我发现%s
应该在它到达空格字符时停止解析。 我发现了这个问题 ,但没有一个答案解决了我遇到的问题:字符串中可能包含任何字符,包括换行符和正确的转义引号。 后者不是问题,如果我可以让sscanf将第一个引用后的所有内容放在我提供的预分配缓冲区中,我可以自行删除结束。
但是我该怎么做? 我不能使用%[]
因为它需要一些东西来终止字符串,我唯一要终止它的是null终止符。 所以我想,“嘿,我只会使用空终结器!” 但%[\0]
让编译器变得脾气暴躁:
warning: no closing ']' for '%[' format warning: embedded '\0' in format warning: no closing ']' for '%[' format warning: embedded '\0' in format
使用像%*c
这样的东西也不会起作用,因为我不确切知道需要采取多少个字符。 我尝试传递strlen(str)
因为它会小于那个,但是sscanf
返回4并且没有任何东西放入str2
,这表明可能因为长度太长而放弃了并且没有打扰。
更新:我想我可以做类似的事情:
sscanf(str,"Stuff<%d,%d,%d,%d,\"%n",&i1,&i2,&i3,&i4,&n); str2 = str+n;
您的更新似乎是一个很好的答案。 在使用sscanf
获取i1
到i4
后,我打算建议strchr
找到第一个引用char的位置。 请注意,您应该始终检查sscanf
的返回值,以确保转换有效。 对于您建议的答案,这一点更为重要,因为如果前四次转换不成功,则n
将保持未初始化状态。
扫描'\"'
,然后扫描所有不是'\"'
,然后再搜索'\"'
。
一定要检查sscanf()
结果并限制测试字符串的长度。
char test_string[100]; int n = 0; if (sscanf(str, "Stuff<%d,%d,%d,%d, \"%99[^\"]\"> %n", &i1, &i2, &i3, &i4, test_string, &n) == 5 && str[n] == '\0') Good();
从sscanf()
观点来看,使用"...%[\0]..."
尝试是"...%["
。
格式为"\0"
所有内容都将被忽略。
使用int n = 0
,将" %n"
附加到格式字符串,将&n
附加到参数并检查str[n] == '\0'
是一个巧妙的技巧,使用sscanf()
来确保整行解析正确。 注意: "%n"
不会添加到sscanf()
结果中。
这不是实现您想要实现的目标的唯一方法,但可能是最好的方法:您需要使用扫描集 。 我不会直接用这个答案告诉你解决方案,我将解释如何使用扫描集,据我所知,你希望自己能够做到这一点。
在分配时,Scansets %[...]
就像%s
一样,它们将值解释为字符并将它们存储到字符数组中。 %s
是以空白为终点的, %[...]
是灵活的版本。
有两种使用扫描组的方法,第一种方法没有前面的插入符号^
,第二种方法是使用前一个插入符号^
。
当您使用没有前面的插入符号^
scanset时,放在括号内的字符将是唯一将被读取,存储然后留下的字符。 一旦scanf
遇到不匹配的字符,那%[...]
就会结束。 例如:
// input: asdasdasdwasdasd char s[100] = { 0 }; scanf( "%[das]", s ); printf( "%s", s ); // output: asdasdasd
将scanset与前面的插入符号^
,搜索将被反转。 它会读取,存储和留下每个角色,直到它到达你在前一个插入符号之后放下的任何一个角色^
。 例:
// input: abcdefgh^kekQ char s[100] = { 0 }; scanf( "%[^Q^]", s ); printf( "%s", s ); // output: abcdefgh
请注意,仍然要在流内读取剩余字符,文件指针不会超出导致终止的字符。 即第一个, getchar( );
会给'w'
,而对于第二个,它会给'^'
。
我希望这就足够了。 如果你仍然找不到出路,请你离开,我可以给你一个解决方案。