【问题标题】:How to split a string to 2 strings in C如何在C中将一个字符串拆分为2个字符串
【发布时间】:2011-02-01 04:21:30
【问题描述】:

我想知道如何获取 1 个字符串,使用分隔符(例如空格)将其拆分为 2 个,然后将 2 个部分分配给 2 个单独的字符串。我试过使用strtok(),但无济于事。

【问题讨论】:

  • 主要是因为字符串不存在,它们是 char 数组,你会发现很难在 C 中拆分字符串
  • 向我们展示您的 strtok() 尝试。
  • 当你说,“我试过使用 strtok(); 但无济于事”,为什么它不起作用?你遇到了什么问题?
  • 你能用strtok()显示你的代码吗?

标签: c string strtok


【解决方案1】:

如果您愿意更改原始字符串,只需将分隔符替换为 \0。原始指针将指向第一个字符串,而指向分隔符之后的字符的指针将指向第二个字符串。好处是您可以同时使用两个指针,而无需分配任何新的字符串缓冲区。

【讨论】:

    【解决方案2】:

    如果您分配了一个 char 数组,您可以简单地将 '\0' 放在您想要的任何位置。 然后将一个新的 char * 指针指向新插入的'\0' 之后的位置。

    这将破坏您的原始字符串,但这取决于您将 '\0' 放在哪里

    【讨论】:

      【解决方案3】:
      #include <string.h>
      
      char *token;
      char line[] = "SEVERAL WORDS";
      char *search = " ";
      
      
      // Token will point to "SEVERAL".
      token = strtok(line, search);
      
      
      // Token will point to "WORDS".
      token = strtok(NULL, search);
      

      更新

      请注意,在某些操作系统上,strtok 手册页提到:

      该接口已被 strsep(3) 废弃。

      strsep 的示例如下所示:

      char* token;
      char* string;
      char* tofree;
      
      string = strdup("abc,def,ghi");
      
      if (string != NULL) {
      
        tofree = string;
      
        while ((token = strsep(&string, ",")) != NULL)
        {
          printf("%s\n", token);
        }
      
        free(tofree);
      }
      

      【讨论】:

      • strtok() 修改其输入,因此在字符串文字上使用它是不好的 juju(也就是未定义的行为)。
      • 是的。我忘了提那个。谢谢。
      • 我想如果你把 char *line = "SEVERAL WORDS" 改成 char line[] = "SEVERAL WORDS",你就准备好了。
      • @ereOn:指针和数组在 C 中是不同的东西,直到你在数组附近打喷嚏,然后它变成一个指针。这就是数组大小表达式sizeof(arr)/sizeof(arr[0]) 的工作原理。
      • strtok() 已过时?哇! strsep() 甚至不是标准 C。
      【解决方案4】:
      char *line = strdup("user name"); // don't do char *line = "user name"; see Note
      
      char *first_part = strtok(line, " "); //first_part points to "user"
      char *sec_part = strtok(NULL, " ");   //sec_part points to "name"
      

      注意:strtok 修改字符串,所以不要给它一个指向字符串字面量的指针。

      【讨论】:

        【解决方案5】:

        你可以使用 strtok() 示例:它适用于我

        #include <stdio.h>
        #include <string.h>
        
        int main ()
        {
            char str[] ="- This, a sample string.";
            char * pch;
            printf ("Splitting string \"%s\" into tokens:\n",str);
            pch = strtok (str," ,.-");
            while (pch != NULL)
            {
                printf ("%s\n",pch);
                pch = strtok (NULL, " ,.-");
            }
            return 0;
        }
        

        【讨论】:

          【解决方案6】:

          出于这样的目的,我倾向于使用 strtok_r() 而不是 strtok()。

          例如...

          int main (void) {
          char str[128];
          char *ptr;
          
          strcpy (str, "123456 789asdf");
          strtok_r (str, " ", &ptr);
          
          printf ("'%s'  '%s'\n", str, ptr);
          return 0;
          }
          

          这将输出...

          '123456''789asdf'

          如果需要更多的分隔符,则循环。

          希望这会有所帮助。

          【讨论】:

          【解决方案7】:

          你可以这样做:

          char str[] ="Stackoverflow Serverfault";
          char piece1[20] = ""
              ,piece2[20] = "";
          char * p;
          
          p = strtok (str," "); // call the strtok with str as 1st arg for the 1st time.
          if (p != NULL) // check if we got a token.
          {
              strcpy(piece1,p); // save the token.
              p = strtok (NULL, " "); // subsequent call should have NULL as 1st arg.
              if (p != NULL) // check if we got a token.
                  strcpy(piece2,p); // save the token.
          }
          printf("%s :: %s\n",piece1,piece2); // prints Stackoverflow :: Serverfault
          

          如果您期望多个令牌,最好在 while 循环中调用第二次和后续调用 strtok,直到 strtok 的返回值变为 NULL

          【讨论】:

          • 看起来不错,除了第二个 strtok() 调用使用了不同的分隔符。
          【解决方案8】:

          这就是您实现strtok() 类函数的方式(取自a BSD licensed string processing library for C, called zString)。

          以下函数与标准strtok() 的区别在于它识别连续分隔符的方式,而标准strtok() 则没有。

          char *zstring_strtok(char *str, const char *delim) {
              static char *static_str=0;      /* var to store last address */
              int index=0, strlength=0;       /* integers for indexes */
              int found = 0;                  /* check if delim is found */
          
              /* delimiter cannot be NULL
              * if no more char left, return NULL as well
              */
              if (delim==0 || (str == 0 && static_str == 0))
                  return 0;
          
              if (str == 0)
                  str = static_str;
          
              /* get length of string */
              while(str[strlength])
                  strlength++;
          
              /* find the first occurance of delim */
              for (index=0;index<strlength;index++)
                  if (str[index]==delim[0]) {
                      found=1;
                      break;
                  }
          
              /* if delim is not contained in str, return str */
              if (!found) {
                  static_str = 0;
                  return str;
              }
          
              /* check for consecutive delimiters
              *if first char is delim, return delim
              */
              if (str[0]==delim[0]) {
                  static_str = (str + 1);
                  return (char *)delim;
              }
          
              /* terminate the string
              * this assignmetn requires char[], so str has to
              * be char[] rather than *char
              */
              str[index] = '\0';
          
              /* save the rest of the string */
              if ((str + index + 1)!=0)
                  static_str = (str + index + 1);
              else
                  static_str = 0;
          
                  return str;
          }
          

          下面是一个演示用法的示例代码

            Example Usage
                char str[] = "A,B,,,C";
                printf("1 %s\n",zstring_strtok(s,","));
                printf("2 %s\n",zstring_strtok(NULL,","));
                printf("3 %s\n",zstring_strtok(NULL,","));
                printf("4 %s\n",zstring_strtok(NULL,","));
                printf("5 %s\n",zstring_strtok(NULL,","));
                printf("6 %s\n",zstring_strtok(NULL,","));
          
            Example Output
                1 A
                2 B
                3 ,
                4 ,
                5 C
                6 (null)
          

          您甚至可以使用 while 循环(标准库的 strtok() 会在此处给出相同的结果)

          char s[]="some text here;
          do {
              printf("%s\n",zstring_strtok(s," "));
          } while(zstring_strtok(NULL," "));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-28
            相关资源
            最近更新 更多