C将一个字符串分成4个变量

时间:2011-10-05 19:18:43

标签: c scanf

我想将一个字符串分成4个部分。我需要的基本上是这样的:

sscanf(string, "%d %d %d %[^\n]", id1, id2, id3, restOfString);

var restOfString是一个char * 问题:restOfString必须指向可能的最小内存空间,并且仍然包含%[^ \ n]指示的所有字符串。

我想要asprintf做什么。它有一个内部malloc(),它创建了打印字符串所需的内存空间。我想为sscanf()使用相同的技术。我怎么能做到这一点?我怎么知道字符串sscanf()的大小会读取?

2 个答案:

答案 0 :(得分:3)

我完全同意RushPL关于不打算微观优化内存的问题。但是在更一般的情况下,你可能有一个大字符串和相对较小的restOfString,这里有一个方法,它将restOfString别名为主字符串:

// char *string, *restOfString;
// int id1, id2, id3, id4;
int result, numStored;
result = sscanf(string, "%d %d %d %d %n", &id1, &id2, &id3, &id4, &numStored);
if (result == 4)
    restOfString = string + numStored;
else
    restOfString = 0;

基本上,使用%n在解析时抓取当前位置,然后将其用作原始字符串的偏移量。请注意,如果不小心使用,%n是非常可能导致格式字符串漏洞的说明符。如果您正在进行复杂的解析,则不应使用scanf和朋友。

答案 1 :(得分:2)

只要使用char* restOfString = malloc(strlen(string));,如果字符串的其余部分太大而无法放入堆栈,那么额外的几个字节就无关紧要了。获得确切的malloc大小会适得其反。

或者,如果我建议,您可以完全跳过分配(但这取决于您的需求)。当sscanf返回元素数和读取的注释字节时,您可以手动找到字符串其余部分的位置。不漂亮,但应该工作。

// sscanf 
sscanf(string, "%d %d %d");
const char* restOfString = strchr(strchr(strchr(string, ' ') + 1, ' ')+1, ' ')+1; // third ' ' +1 gives rest of string

或者,您可以使用以下方式获得准确的分配:

char* restOfStringAlloced = strdup(restOfString);