我做了一些研究,想要查找 sscanf()
的源代码。但是我没有找到答案。
当我们以如下方式使用 sscanf()
:
char str[50] = "5,10,15";
int x;
sscanf(str,"%d,%s",&x,str);
sscanf()函数是否支持“递归”缓冲区str?
它不会从自我修改的缓冲区中断开。但要使其(尾部)递归,您必须读取到字符串的末尾。
代码片段:
char str[]="5,10,15";
int a[10]={0},x = 0;
while (sscanf(str,"%d,%s",a+ x++,str)>1);
读取所有整数。
由于这不是真正的递归,并且要读取的字符串不会覆盖字符串中的asciiz,我相信这在意义上是“安全”的:只能在家里尝试。
scanf系列函数逐个读取格式说明符并进行转换。在您的示例代码中:
char str[50] = "5,10,15";
int x;
sscanf(str,"%d,%s",&x,str);
可能会起作用,因为它首先读取一个整数和另一个C字符串。原始的str
被新值覆盖,这里没有问题。
但考虑以下情况:
char str[50] = "5 10 15";
int x;
sscanf(str,"%s %d",str, &x);
这段代码首先从原始值中读取5
,并覆盖了str
,由于前一个%s
的空终止符,str
的末尾已经被读取完毕,因此后续的格式说明符%d
无法从str
中读取任何内容。
这只是一个反例,用来说明这是一个不好的想法,并且不起作用。因此可以说这将在某个时候引发未定义的行为或导致其他问题。
strchr()
查找下一个分隔符,并更新字符串指针以指向下一个字符。使用strtok()
解决了我曾经遇到的一个几乎相同的问题,即递归地使用sscanf()
从char*
中提取内容(一串由空格分隔的double列表,例如"1.00 2.01 ..."
),并将其转换为double数组(例如array[1]=1.00
,array[2]=2.01
,...)。
如果我理解你的问题正确,以下内容可能会有所帮助:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char str[]= "5,10,15";
char* token;
int x[3];
token = strtok(str, ",");
for(int i=0; i<3; i++){
sscanf(token, "%d", &x[i]);
token = strtok(NULL, ",");
}
for(int i=0; i<3; i++) printf("%d\n", x[i]);
return 0;
}
运行时,它会产生:
5
10
15
strtok()
的有用描述。
restrict
限定词。在参数列表中传递另一个指向str
的指针可能会违反restrict
承诺,但我对此并不完全确定。 - Mat