sscanf()是否支持"递归"缓冲?

时间:2012-11-27 10:28:39

标签: c scanf

我进行了一些研究,以便查找sscanf()源代码。但我无法找到问题的答案。

当我们以这种方式使用sscanf()时:

char str[50] = "5,10,15";
int x;
sscanf(str,"%d,%s",&x,str);

sscanf()是否支持“递归”缓冲区str

4 个答案:

答案 0 :(得分:3)

它不会从自修改缓冲区中断。但要使它(尾部)递归,你必须读到字符串的末尾 代码片段:

char str[]="5,10,15";
int a[10]={0},x = 0; 
while (sscanf(str,"%d,%s",a+ x++,str)>1);

读取所有整数。

由于这不是真正的递归,并且要读取的字符串不会覆盖字符串中的asciiz,我相信这是“安全”的含义:只在家里试试。

答案 1 :(得分:3)

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,后续格式说明符%d将无法从str读取str的结尾由于前一次%s读取的nul-termination,已达到}。

这只是一个反例,表明这是一个坏主意,不会奏效。所以你可以说这会在某个时候调用未定义的行为或导致其他问题。

答案 2 :(得分:1)

一般来说,我会建议不要这样做。如果它不起作用,它将在所有角落的情况下。要确定,您必须检查您正在使用的实现的来源。如果您希望它是可移植的,请立即忘记它,除非您将其视为libc规范中的保证行为。使用strchr()查找下一个分隔符并更新字符串指针以指向下一个字符。

答案 3 :(得分:0)

使用strtok()解决了我遇到的几乎相同的问题,即递归地使用sscanf()来提取char*的内容(由空格分隔的双精度列表,例如"1.00 2.01 ...")成双数组(例如array[1]=1.00array[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()的有用说明,请参阅http://www.cplusplus.com/reference/cstring/strtok/