如何在运行时更改格式说明符的值?

时间:2013-08-23 11:30:02

标签: c++ c scanf format-specifiers

我在项目中使用 sscanf 将字符串从源缓冲区复制到目标缓冲区。 例如:

char* target;
target = (char*)malloc(100 * sizeof(char));
char* source = "Hello World";
sscanf(source, "%[^\t\n]", target); // trying to copy "Hello World" into target.
printf("%s\n", target);//this will print "Hello World".

但这种编码方式不被接受。我的经理要我做的是:

sscanf(source, "%11[^\t\n]", target); // NOTE: I've written "%11". here, 11 == length of hello world.

这意味着,他还希望我提供格式说明符。 (在这种情况下为%11)。

但是,问题是源的长度可能不同,我不知道如何为每个变长字符串编写正确的格式说明符。

4 个答案:

答案 0 :(得分:7)

<击>使用:

<击>
sscanf(source, "%*[^\t\n]", maxlen, target)

其中maxlen是您要阅读的大小。

似乎没有简单的方法可以使sscanf(或其任何兄弟姐妹)的格式字符串占用输入字符串的任意最大长度。该建议基于printfscanf正交,结果并非如此。

您可能会发现使用strtok以及strncpystrdup来复制令牌会更好。

但是,由于它标记为C ++,为什么不使用:

std::stringstream ss(source);  
std::string target;
getline(ss, target, "\t");

答案 1 :(得分:0)

复制字符串使用strcpy()。它不分配空间,所以你也必须提供第二个缓冲区。还有strncpy(),它不会复制超过指定的字符。

如果你想一次性复制一个字符串,你可以使用strdup(),不要忘记随后释放内存。

答案 2 :(得分:0)

首先,为此使用strcpy()。

其次,格式说明符只是一个字符串,所以在使用所需字符串的strlen()后,只需使用sprintf()来创建它。

答案 3 :(得分:0)

使用target = strdup(source)或仍有义务使用sscanf()

动态创建格式。

const char* source = "Hello World";
size_t n = 10;  // See note below
char* target;
target = (char*) malloc(n);  // (char *) is needed for C++, but not C
char format[1+20+5+1];
sprintf(format, "%%" "%zu" "[^\t\n]", n - 1);
sscanf(source, format, target); // trying to copy "Hello World" into target.
printf("%s\n", source);//this will print "Hello World".
printf("%s\n", target);//this will print "Hello Wor".

您可能需要n = strlen(source) + 1,但上面说明了动态创建的scanf()格式说明符如何防止target中的缓冲区溢出。