【问题标题】:How to split string in C without using strtok如何在不使用 strtok 的情况下在 C 中拆分字符串
【发布时间】:2012-09-06 18:40:36
【问题描述】:
#include <stdio.h>
int
main() {
    char string[] = "my name is geany";
    int length = sizeof(string)/sizeof(char);
    printf("%i", length);
    int i;
    for ( i = 0; i<length; i++ ) {

    }   
    return 0;
}

如果我想分别打印“my”“name”“is”和“geany”,我该怎么办。我正在考虑使用分隔符,但我不知道如何在 C 中使用它

【问题讨论】:

  • 我正在探索 C 并且遇到了这个
  • @Tudor 因为你经常收到一个 const char* 并且如果不复制整个字符串就不能使用 strtok (当我们不知道字符串来自哪里时,丢弃 const 是不安全的)。

标签: c string token


【解决方案1】:
use strchr to find the space.
store a '\0' at that location.
the word is now printfable.

repeat
    start the search at the position after the '\0'
    if nothing is found then print the last word and break out
    otherwise, print the word, and continue the loop

【讨论】:

    【解决方案2】:
    1. 以指向字符串开头的指针开始
    2. 逐个字符迭代,寻找你的分隔符
    3. 每次找到一个时,您都会得到一个与长度不同的最后一个位置的字符串 - 用它做您想做的事情
    4. 将新的起始位置设置为分隔符 + 1,然后转到第 2 步。

    在字符串中还有字符时执行所有这些操作...

    【讨论】:

      【解决方案3】:

      重新发明轮子通常是个坏主意。学会使用实现函数也是一种很好的训练。

      #include <string.h>
      
      /* 
       * `strtok` is not reentrant, so it's thread unsafe. On POSIX environment, use
       * `strtok_r instead. 
       */
      int f( char * s, size_t const n ) {
          char * p;
          int    ret = 0;
          while ( p = strtok( s, " " ) ) { 
              s += strlen( p ) + 1; 
              ret += puts( p ); 
          }
          return ret;
      }
      

      【讨论】:

        【解决方案4】:

        这会在换行符处断开字符串并修剪报告字符串的空白。它不会像 strtok 那样修改字符串,这意味着它可以用于来源未知的const char*,而 strtok 不能。不同之处在于 begin/end 是指向原始字符串字符的指针,因此不像 strtok 给出的那样以空字符结尾的字符串。当然,这使用静态本地,因此不是线程安全的。

        #include <stdio.h> // for printf
        #include <stdbool.h> // for bool
        #include <ctype.h> // for isspace
        
        static bool readLine (const char* data, const char** beginPtr, const char** endPtr) {
            static const char* nextStart;
            if (data) {
                nextStart = data;
                return true;
            }
            if (*nextStart == '\0') return false;
            *beginPtr = nextStart;
        
            // Find next delimiter.
            do {
                nextStart++;
            } while (*nextStart != '\0' && *nextStart != '\n');
        
            // Trim whitespace.
            *endPtr = nextStart - 1;
            while (isspace(**beginPtr) && *beginPtr < *endPtr)
                (*beginPtr)++;
            while (isspace(**endPtr) && *endPtr >= *beginPtr)
                (*endPtr)--;
            (*endPtr)++;
        
            return true;
        }
        
        int main (void) {
            const char* data = "  meow ! \n \r\t \n\n  meow ?  ";
            const char* begin;
            const char* end;
            readLine(data, 0, 0);
            while (readLine(0, &begin, &end)) {
                printf("'%.*s'\n", end - begin, begin);
            }
            return 0;
        }
        

        输出:

        'meow !'
        ''
        ''
        'meow ?'
        

        【讨论】:

          【解决方案5】:

          我需要这样做,因为正在运行的环境有一个缺少 strtok 的受限库。以下是我如何拆分连字符分隔的字符串:

               b = grub_strchr(a,'-');
               if (!b)
                 <handle error>
               else
                 *b++ = 0;
          
               c = grub_strchr(b,'-');
               if (!c)
                 <handle error>
               else
                 *c++ = 0;
          

          这里,a 以复合字符串 "A-B-C" 的形式开始生命,代码执行后,有三个以 null 结尾的字符串 abc,其值为 "A""B""C"&lt;handle error&gt; 是一个占位符,用于代码对缺少的分隔符做出反应。

          请注意,与 strtok 一样,原始字符串会通过将分隔符替换为 NULL 来修改。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-08-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-09
            相关资源
            最近更新 更多