如何在C语言中不使用strtok函数拆分字符串

7
#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;
}

如果我想单独打印“我的”,“名字”,“是”和“geany”,我该怎么办。我在考虑使用分隔符,但我不知道如何在C语言中实现。

我正在探索C语言,然后遇到了这个。 - larzgmoc
3
由于您经常收到const char*,而且不能在不复制整个字符串的情况下使用strtok(当我们不知道字符串来自何处时,强制转换const是不安全的),因此需要注意。 - NateS
5个回答

12
  1. 从字符串开头开始使用指针
  2. 逐个字符迭代,寻找分隔符
  3. 每次发现一个分隔符时,你就有了一个长度为差值的自上一位置的字符串 - 对其进行任意操作
  4. 将新的起始位置设置为分隔符+1,并返回到步骤2。

当字符串中还有剩余字符时,执行这些步骤...


2

我需要这样做是因为我所使用的环境有一个受限制的库,缺少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"开始生命周期,代码执行后,会有三个以空字符结尾的字符串abc,它们的值分别是"A""B""C"。其中<handle error>是一个占位符,用于处理缺少分隔符的情况。
请注意,类似于strtok,原始字符串被修改以替换分隔符为NULL值。

1
这个函数会在换行处分割字符串并修剪报告字符串的空格。它不像strtok那样修改字符串,因此可以用于未知来源的const char*,而strtok则不能。区别在于begin/end是指向原始字符串字符的指针,因此不像strtok返回null终止字符串。当然,这使用了静态局部变量,因此不是线程安全的。
#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 ?'

0
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

-4

重复造轮子通常不是一个好主意。学会使用实现函数也是一个很好的训练。

#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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接