C-不能将strcpy与strtok一起使用

C-不能将strcpy与strtok一起使用,c,strtok,strcpy,C,Strtok,Strcpy,我正在使用一个函数,该函数接受全名作为输入,并按顺序打印出来:名字、中间名、姓氏 问题是我的while循环似乎是无限的,我还没有找到解决方法 以下是我的功能: void order(char ar[]) { int i, count=0, a=1; char* token; char last[20], middle[20], first[20],c; char s[]=" "; for(i=0;i<strlen(ar)-1;i++)

我正在使用一个函数,该函数接受全名作为输入,并按顺序打印出来:名字、中间名、姓氏

问题是我的while循环似乎是无限的,我还没有找到解决方法

以下是我的功能:

void order(char ar[])
{
    int i, count=0, a=1;
    char* token;
    char last[20], middle[20], first[20],c;
    char s[]=" ";
    for(i=0;i<strlen(ar)-1;i++)
        if(ar[i]==' ') count++;

    token=strtok(ar,s);
    strcpy(last,token);


    while(token!=NULL)
    {
        token=strtok(NULL,s);
        if(a<count) strcpy(middle,token);
        else strcpy(first,token);
        a++; 
    }
    printf("%s %s %s",first,middle,last);
}
无效订单(char ar[]
{
int i,计数=0,a=1;
字符*令牌;
字符最后[20],中间[20],第一[20],c;
字符s[]=“”;
对于(i=0;i当复制第一个时(即标识所有令牌),将再次输入while循环(注意,令牌不是NULL,但在本例中指向第一个)。现在将调用strtok(),它将返回NULL。代码将转到else部分并尝试strcpy(),这是导致问题的原因

在strcpy()之前检查NULL。我这样做过,效果很好

while(token!=NULL)                                                          
{                                                                           
    token=strtok(NULL,s);                                                   
    if (token == NULL)                                                      
      break;                                                                
    if(a<count) strcpy(middle,token);                                       
    else strcpy(first,token);                                               
    a++;                                                                    
} 
while(令牌!=NULL)
{                                                                           
令牌=strtok(空,s);
if(标记==NULL)
打破
如果(a当复制第一个时(即识别所有令牌),则将再次输入while循环(注意,令牌不是NULL,但在本例中指向第一个)。现在将调用strtok(),它将返回NULL。代码将转到else部分并尝试strcpy(),这是导致问题的原因

在strcpy()之前检查NULL。我这样做过,效果很好

while(token!=NULL)                                                          
{                                                                           
    token=strtok(NULL,s);                                                   
    if (token == NULL)                                                      
      break;                                                                
    if(a<count) strcpy(middle,token);                                       
    else strcpy(first,token);                                               
    a++;                                                                    
} 
while(令牌!=NULL)
{                                                                           
令牌=strtok(空,s);
if(标记==NULL)
打破

如果(a这更像是我在问题中呈现代码的方式-在我将其传递给编译器之前:

void order(char ar[])
{
    int count = 0, a = 1;
    char *token;
    char last[20], middle[20], first[20];
    char s[] = " ";

    for (int i = 0; i < strlen(ar) - 1; i++)
    {
        if (ar[i] == ' ')
            count++;
    }

    token = strtok(ar, s);
    strcpy(last, token);

    while (token != NULL)
    {
        token = strtok(NULL, s);
        if (a < count)
            strcpy(middle, token);
        else
            strcpy(first, token);
        a++;
    }
    printf("%s %s %s", first, middle, last);
}
无效订单(char ar[]
{
整数计数=0,a=1;
字符*令牌;
字符最后[20],中间[20],第一[20];
字符s[]=“”;
对于(int i=0;i
你可以争论大括号的位置-我使用1TB,但它是一种广泛使用的替代样式。我建议选择这两种样式中的一种。如果循环体不止一行,我会在循环体周围放置大括号;YMMV

在运算符周围使用更多空格。不要定义未使用的变量(
c
消失)。我将
int I
放在
for
循环中。我可能会每行定义一个变量,并且可能不会使用
计数
a

strlen()
的调用不应处于循环状态。我不确定您将如何处理我的名字-我没有中间名。我认为您可以完全避免
while
循环。我不相信您也需要
进行
循环。这些是单独的讨论


我没有试图解决算法问题-这不是问题中问题的答案(因此不应接受),但是中问题的答案,由于代码不能在注释中格式化,我无法在注释中理智地回答它;因此,这“不是答案”,而是“旨在对OP中的辅助问题有所帮助”。

这更像是我在通过编译器之前在问题中呈现代码的方式:

void order(char ar[])
{
    int count = 0, a = 1;
    char *token;
    char last[20], middle[20], first[20];
    char s[] = " ";

    for (int i = 0; i < strlen(ar) - 1; i++)
    {
        if (ar[i] == ' ')
            count++;
    }

    token = strtok(ar, s);
    strcpy(last, token);

    while (token != NULL)
    {
        token = strtok(NULL, s);
        if (a < count)
            strcpy(middle, token);
        else
            strcpy(first, token);
        a++;
    }
    printf("%s %s %s", first, middle, last);
}
无效订单(char ar[]
{
整数计数=0,a=1;
字符*令牌;
字符最后[20],中间[20],第一[20];
字符s[]=“”;
对于(int i=0;i
你可以争论大括号的位置-我使用1TB,但它是一种广泛使用的替代样式。我建议选择这两种样式中的一种。如果循环体不止一行,我会在循环体周围放置大括号;YMMV

在运算符周围使用更多空格。不要定义未使用的变量(
c
消失)。我将
int I
放在
for
循环中。我可能会每行定义一个变量,并且可能不会使用
计数
a

strlen()
的调用不应处于循环状态。我不确定您将如何处理我的名字-我没有中间名。我认为您可以完全避免
while
循环。我不相信您也需要
进行
循环。这些是单独的讨论


我没有试图解决算法问题-这不是问题中问题的答案(因此不应接受),但这是中问题的答案,由于代码不能在注释中格式化,我无法在注释中理智地回答它;因此,这“不是答案”,而是“旨在帮助解决OP中的辅助问题”。

如图所示的代码非常难阅读-正统布局样式有其优点,其中之一是它们是可读性,另一个是熟悉性。在复制之前,你必须检查strtok是否返回NULL。如果名称的各个部分之间,或者在开头或结尾有几个相邻的空格,会发生什么情况?你也不检查