用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获取i1i4后,我打算建议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' ,而对于第二个,它会给'^'

我希望这就足够了。 如果你仍然找不到出路,请你离开,我可以给你一个解决方案。