C 使用strtok吐出数组,并将令牌存储在唯一的以null结尾的字符串中

C 使用strtok吐出数组,并将令牌存储在唯一的以null结尾的字符串中,c,strtok,C,Strtok,我有一个字符串数组cmd,其容量为255个字符,声明方式如下: char cmd[255]; fgets(cmd, 256, stdin); char arg[20]; char arg2[20]; char arg3[20]; char *p = strtok(cmd, " "); while (p!= NULL) { // I want to store the tokens p in the arrays here (e.g: // arg = p is not working

我有一个字符串数组cmd,其容量为255个字符,声明方式如下:

char cmd[255];
fgets(cmd, 256, stdin);
char arg[20];
char arg2[20];
char arg3[20];
char *p = strtok(cmd, " ");

while (p!= NULL) {

// I want to store the tokens p in the arrays here (e.g:
// arg = p is not working
// arg2 = p ...

p = strtok(NULL, " ");
}
我使用FGET以这种方式获取用户输入:

char cmd[255];
fgets(cmd, 256, stdin);
char arg[20];
char arg2[20];
char arg3[20];
char *p = strtok(cmd, " ");

while (p!= NULL) {

// I want to store the tokens p in the arrays here (e.g:
// arg = p is not working
// arg2 = p ...

p = strtok(NULL, " ");
}
我有三个单独的数组来存储三个令牌(假设用户只输入一个最多包含2个空格的字符串),声明方式如下:

char cmd[255];
fgets(cmd, 256, stdin);
char arg[20];
char arg2[20];
char arg3[20];
char *p = strtok(cmd, " ");

while (p!= NULL) {

// I want to store the tokens p in the arrays here (e.g:
// arg = p is not working
// arg2 = p ...

p = strtok(NULL, " ");
}
我使用strtok在cmd中拆分字符串,方法如下:

char cmd[255];
fgets(cmd, 256, stdin);
char arg[20];
char arg2[20];
char arg3[20];
char *p = strtok(cmd, " ");

while (p!= NULL) {

// I want to store the tokens p in the arrays here (e.g:
// arg = p is not working
// arg2 = p ...

p = strtok(NULL, " ");
}
以这种方式分配指针中的值不起作用。你能帮我做些什么吗


我必须将令牌存储在以null结尾的字符串中

以下操作可能有效

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char cmd[255] = "";
    char arg[20]  = "" ;
    char arg2[20] = "";
    char arg3[20] = "";
    char *p;

    fgets(cmd, 255, stdin );

    p = strtok(cmd, " ");
    if ( p != NULL ) {
        strcpy( arg, p );
        p = strtok(NULL, " ");
        if ( p != NULL ) {
            strcpy( arg2, p );
            p = strtok(NULL, "");
            if ( p != NULL ) {
                strcpy( arg3, p );
            }
        }
    }


    printf(" arg=%s\n arg2=%s\n arg3=%s\n", arg, arg2, arg3);

    return 0;
}
#包括
#包括
#包括
int main()
{
char cmd[255]=“”;
字符arg[20]=“”;
字符arg2[20]=“”;
字符arg3[20]=“”;
char*p;
fgets(cmd,255,stdin);
p=strtok(cmd,“”);
如果(p!=NULL){
strcpy(arg,p);
p=strtok(空,“”);
如果(p!=NULL){
strcpy(arg2,p);
p=strtok(空,“”);
如果(p!=NULL){
strcpy(arg3,p);
}
}
}
printf(“arg=%s\n arg2=%s\n arg3=%s\n”,arg,arg2,arg3);
返回0;
}

建议:声明argv如下

 char argv[3][20];
通过这样做,它将简化代码,如下所示:

int
main(void)
{
   char cmd[255];
   char argv[3][20];
   char *token;
   char *tstr = " ";

   fgets( cmd, sizeof cmd, stdin );

   token = strtok( cmd, tstr );
   int i = 0;

   while( token != NULL )
   {
        strcpy( argv[i], token);
        printf( "%s\n", argv[i] );
        token = strtok( NULL, tstr ); 
        i++;
   }

   return 0;
}
像这样:

#include <stdio.h>
#include <string.h>

#define ARG_LEN 20

int main(void){
    char cmd[256];

    if(fgets(cmd, sizeof cmd, stdin)){
        char arg[ARG_LEN+1], arg2[ARG_LEN+1], arg3[ARG_LEN+1];
        char *args[] = { arg, arg2, arg3, NULL };
        char **pp = args;
        const char *delimiter = " \t\n";//Include \n

        for(char *p = strtok(cmd, delimiter); p && *pp; p = strtok(NULL, delimiter)){
            strncpy(*pp, p, ARG_LEN);
            (*pp++)[ARG_LEN] = 0;//Cut it if it is too long
        }
        for(size_t i = 0; args + i < pp; ++i){
            printf("argument #%zu: '%s'\n", i+1, args[i]);
        }
    }
}
#包括
#包括
#定义ARG_LEN 20
内部主(空){
char-cmd[256];
如果(fgets(cmd,sizeof cmd,stdin)){
字符arg[arg_LEN+1]、arg2[arg_LEN+1]、arg3[arg_LEN+1];
char*args[]={arg,arg2,arg3,NULL};
字符**pp=args;
常量字符*分隔符=“\t\n”//包括\n
for(char*p=strtok(cmd,分隔符);p&&*pp;p=strtok(NULL,分隔符)){
strncpy(*pp,p,ARG_LEN);
(*pp++)[ARG_LEN]=0;//如果太长,请将其剪切
}
对于(大小i=0;参数+i

sscanf版本

#include <stdio.h>

//Stringification
#define S_(n) #n
#define S(n) S_(n)

#define FMT "%" S(ARG_LEN) "s"

#define ARG_LEN 20

int main(void){
    char cmd[256];

    if(fgets(cmd, sizeof cmd, stdin)){
        char arg[ARG_LEN+1], arg2[ARG_LEN+1], arg3[ARG_LEN+1];
        char *args[] = { arg, arg2, arg3 };
        int ret_scnf = sscanf(cmd, FMT FMT FMT, arg, arg2, arg3);
        for(int i = 0; i < ret_scnf; ++i){
            printf("argument #%i: '%s'\n", i+1, args[i]);
        }
    }
}
#包括
//严格化
#定义S_n(n)#n
#定义S(n)S_n(n)
#定义FMT“%”S(参数)“S”
#定义ARG_LEN 20
内部主(空){
char-cmd[256];
如果(fgets(cmd,sizeof cmd,stdin)){
字符arg[arg_LEN+1]、arg2[arg_LEN+1]、arg3[arg_LEN+1];
char*args[]={arg,arg2,arg3};
int ret_scnf=sscanf(cmd、FMT、FMT、arg、arg2、arg3);
对于(int i=0;i
spit->split。C不会吐!!!:)NUL字符为“\0”,不为空。这有很大的区别。正确的措辞是“NUL终止字符串”,而不是“null终止…”NUL是一个“\0”,其中null因平台而异。它通常是(void*)0。
fgets(cmd,256,stdin)关闭一个错误-->
fgets(cmd,255,stdin)
fgets(cmd、sizeof cmd、stdin)
,或
charcmd[255]-->
charcmd[256]
@Nguaial如果它说“
NULL
terminated string”,你就对了。但是,“以null结尾的字符串”是正确的,因为ASCII代码为0的字符称为null字符(也称为NUL,也称为
'\0'
)。如果参数太长,则两个代码的行为将不同。太好了。代码保留了指定的所有原始变量名。我有一个问题:由于后增量比反引用运算符具有更高的优先级,所以不应该是(*pp)[ARG_LEN]=0;pp++;所以,在你移动到下一个之前,你要切断电流。是的。这证明了您的代码是正确的。谢谢