使用strtok_s时第二个值始终为NULL,如何获取两个分割值?
问题
在C语言中使用strtok_s函数拆分空格分隔的用户输入时,始终只能获取第一部分,第二部分的值始终为NULL。目标是将输入拆分为两部分并通过指针返回,例如输入cd C://时,期望得到第一部分为cd,第二部分为C://,但实际第二部分始终为空。
原代码如下:
void argGetter(char* commandDesired, char** firstArg, char** secondArg) { // this char holds the first part of the command before the " " char* commandCleanDesired; // this char array holds the part after the " " char *nextToken; char *argument; commandCleanDesired = strtok_s(commandDesired, " ", &nextToken); argument = strtok_s(NULL, " ", &nextToken); printf("\n\nCMD 1 is %s\n\nCMD 2 is %s\n\n\n", commandCleanDesired, argument); *firstArg = commandCleanDesired; *secondArg = argument; } //this shows how argGetter is called. void main() { // these hold the return values from argGetter() char* secondArg = NULL; char* firstArg = NULL; //This holds user input char commandDesired[255]; //This line prints the prompt printf("\n\tSanity$hell> "); //Then we get user input scanf_s("%s", commandDesired, 255); //split the command from args using argGetter argGetter(commandDesired, &firstArg, &secondArg); printf("\n First Arg is %s\n", firstArg); printf("\nYour second arg is %s\n\n", secondArg); }
尝试过的修改(均未成功):
commandCleanDesired = strtok_s(commandDesired, " ", &commandDesired); argument = strtok_s(commandDesired, " ", &commandDesired); //the above resulted in NULL for the second value argument as well. // Below is the next thing i tried. char * nextToken; commandCleanDesired = strtok_s(commandDesired, " ", &nextToken); argument = strtok_s(NULL, " ", &nextToken); //both result in argument being NULL. //I tried the above after reading the manual more.
问题原因
核心错误不在strtok_s的使用,而是输入读取阶段的问题:
scanf_s("%s", ...)会在遇到空格、换行符等空白字符时停止读取,所以当输入cd C://时,commandDesired中只会存储cd,后面的C://根本没被读入。- 后续调用
strtok_s时,字符串里只有cd,自然拆分不出第二个token,返回NULL。
修复方案
替换scanf_s为能读取包含空格的整行输入的函数,比如fgets,同时注意处理fgets会读取换行符的问题。修改后的完整代码如下:
#include <stdio.h> #include <string.h> void argGetter(char* commandDesired, char** firstArg, char** secondArg) { char* commandCleanDesired; char *nextToken; char *argument; // 去掉fgets读入的换行符 size_t len = strlen(commandDesired); if (len > 0 && commandDesired[len-1] == '\n') { commandDesired[len-1] = '\0'; } commandCleanDesired = strtok_s(commandDesired, " ", &nextToken); argument = strtok_s(NULL, " ", &nextToken); printf("\n\nCMD 1 is %s\n\nCMD 2 is %s\n\n\n", commandCleanDesired, argument); *firstArg = commandCleanDesired; *secondArg = argument; } int main() { // 标准main返回类型为int char* secondArg = NULL; char* firstArg = NULL; char commandDesired[255]; printf("\n\tSanity$hell> "); // 使用fgets读取整行输入,包含空格 fgets(commandDesired, sizeof(commandDesired), stdin); argGetter(commandDesired, &firstArg, &secondArg); printf("\n First Arg is %s\n", firstArg); printf("\nYour second arg is %s\n\n", secondArg); return 0; }
补充说明:
fgets会把输入的换行符也读进数组,手动替换为\0可以避免后续处理出现异常。- 标准C规范中
main函数的返回类型应为int,而非void,修正后更符合代码规范。
内容的提问来源于stack exchange,提问作者BoundedLeap
相关产品推荐
相关产品推荐

