迭代字符串并用C中的空格分隔输入

时间:2015-06-27 18:00:22

标签: c string loops pointers

我有一个字符串,例如"第一个"我想要的结果是这个输出:

first 
second

但我得到的输出是:

first
first second

我知道在我的更新语句或创建子字符串时都存在问题。如果有人能帮助我,那就太棒了。以下是我的代码:

int counter = 0; //counter used in loop
int index = test->current_index; //holds the current index of my string, it's initially 0
char *string = test->myString; //holds the whole string

char token_buffer = string[index];

   //before loop: index = 0, counter = 0

   while(test->current_index <= test->end_index) //test->end_index holds last index of string

    {
       while(token_buffer != ' ')
       {
         counter++;
         token_buffer = string[index + counter];

       }    

    char *output_token = malloc(counter+1);


   strncpy( output_token, string, counter );

  //printing token
  printf("%s \n", output_token);


 //update loop (possible problem area!)
  test->current_index += counter;
  index += counter;
  token_buffer+=string[counter];
  counter =0;
  }

return 0;
}

3 个答案:

答案 0 :(得分:3)

有许多方法可以将字符串拆分为在空格中分隔它们的标记。诀窍是使其尽可能高效且相当稳健,而不会使其过于复杂。两种基本方法是使用(1)“inch-worm”方法(简单地使用2个指针,一个开始和结束指针,一次处理字符串一个字符,或者(2)使用其中一个标记化libc提供的功能(例如strtokstrsep)。

使用英制蠕虫方法,您可以完全控制并具有竞争灵活性,但是当您按下字符串时,可以 跟踪每个指针指向的位置。 (熟悉这种方法的一个好方法是在 paper 上编写你正在解析的字符串,并根据需要手动推进指针 - 编写你的例程)。一个例子:

char *string = test->myString; //holds the whole string
char *p = string;

while (*p)                      /* while not end of string */
{
    char *sp = p;                  /* set a start pointer */
    while (*p && *p != ' ') p++;   /* advance to space    */
    char *output_token = malloc (p - sp + 1); /* allocate */
    strncpy (output_token, sp, p - sp);         /* copy   */
    output_token[p - sp] = 0;   /* force null-termination */
    printf("   %s\n", output_token); 
    free (output_token);           /* free if not needed  */
    while (*p && *p == ' ') p++;   /* find next non-space */
}

第二种方法使用strtok做同样的事情。 注意:您可以随意在分隔符字符串中放置任意数量的字符,并且不要求每次调用strtok时它们都是相同的字符。这可以提供很大的灵活性。一个例子:

char *string = test->myString; //holds the whole string
char *p = string;   /* pointer to string */
char *tok = NULL;   /* pointer to token  */

for (tok = strtok (p, " "); tok; tok = strtok (NULL, " \n"))
{
    char *output_token = strdup (tok);  /* allocate & copy at once */
    printf("   %s\n", output_token);
    free (output_token);
}

如果您想将两者与示例进行比较,可以使用以下简短示例:

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

int main (int argc, char **argv) {

    // char *string = test->myString; //holds the whole string
    char *string = argc > 1 ? argv[1]: "some string with spaces";

    printf ("\n With pointer arithmetic:\n\n");

    char *p = string;
    while (*p)                     /* while not end of string */
    {
        char *sp = p;                  /* set a start pointer */
        while (*p && *p != ' ') p++;    /* advance to space   */
        char *output_token = malloc (p - sp + 1); /* allocate */
        strncpy (output_token, sp, p - sp);         /* copy   */
        output_token[p - sp] = 0;   /* force null-termination */
        printf("   %s\n", output_token); 
        free (output_token);           /* free if not needed  */
        while (*p && *p == ' ') p++;   /* find next non-space */
    }


    printf ("\n With strtok:\n\n");

    p = string;
    char *tok = NULL;      /* pointer to each token in string */

    /* using strtok to separate string into tokens at spaces  */
    for (tok = strtok (p, " "); tok; tok = strtok (NULL, " \n"))
    {
        char *output_token = strdup (tok);
        printf("   %s\n", output_token);
        free (output_token);
    }

    return 0;
}

示例/输出

$ ./bin/charbufsplit "This is a longer string with many more  spaces"

 With pointer arithmetic:

   This
   is
   a
   longer
   string
   with
   many
   more
   spaces

 With strtok:

   This
   is
   a
   longer
   string
   with
   many
   more
   spaces

答案 1 :(得分:0)

问题似乎是调用strncpy。 用:

strncpy( output_token, string, counter );

您正在复制counter string开头的output_token个字符。要致电strncpy,您最常将源字符串移至current_index。类似的东西:

strncpy( output_token, (char*)(string+test->current_index), counter );

在循环结束时。

答案 2 :(得分:0)

您的代码中有两个错误:

  1. strncpy中,每次复制到output_token时,您都会从string的起始地址开始复制。
  2. while循环条件token_buffer != ' '中。由于在字符串末尾,您没有空格,因此您的计数器将继续增加并超出test->end_index,直到它读取空格。
  3. 校正:

    counter = 0;
    token_buffer = string[counter+index];
    while(token_buffer != ' ' && (index+counter)<=test->end_index) //since counter is always set to zero before this loop executes.
    {
        counter++;
        token_buffer = string[index+counter];
    }
    
    char *output_token = calloc(counter+1);
    strncpy(output_token,string+index,counter);
    printf("%s \n", output_token);
    counter++;    //This is required since when the loop exit, counter would be at the position of ' '.
    test->current_index += counter;
    index += counter;
    

    在主循环中添加此内容。