简体   繁体   English

如何在不使用strtok的情况下在C中拆分字符串

[英]How to split string in C without using strtok

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

if i want to print "my" "name" "is" and "geany" separate then what do I do.如果我想将“我的”“姓名”“是”和“geany”分开打印,那么我该怎么办。 I was thinking to use a delimnator but i dont know how to do it in C我想使用定界符,但我不知道如何在 C 中使用

  1. start with a pointer to the begining of the string以指向字符串开头的指针开始
  2. iterate character by character, looking for your delimiter逐个字符地迭代,寻找你的分隔符
  3. each time you find one, you have a string from the last position of the length in difference - do what you want with that每次你找到一个时,你都会从长度差的最后一个位置得到一个字符串 - 用它做你想做的
  4. set the new start position to the delimiter + 1, and the go to step 2.将新的开始位置设置为分隔符 + 1,然后转到步骤 2。

Do all these while there are characters remaining in the string...在字符串中剩余字符时执行所有这些操作...

I needed to do this because the environment was working in had a restricted library that lacked strtok .我需要这样做,因为工作环境有一个缺少strtok的受限库。 Here's how I broke up a hyphen-delimited string:以下是我如何拆分以连字符分隔的字符串:

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

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

Here, a begins life as the compound string "ABC" , after the code executes, there are three null-terminated strings, a , b , and c which have the values "A" , "B" and "C" .在这里, a以复合字符串"ABC" ,在代码执行后,有三个以空字符结尾的字符串abc ,它们的值分别为"A""B""C" The <handle error> is a place-holder for code to react to missing delimiters. <handle error>是代码的占位符,用于对缺少的分隔符做出反应。

Note that, like strtok , the original string is modified by replacing the delimiters with NULLs.请注意,与strtok一样,通过用 NULL 替换分隔符来修改原始字符串。

This breaks a string at newlines and trims whitespace for the reported strings.这会在换行符处中断字符串并为报告的字符串修剪空格。 It does not modify the string like strtok does, which means this can be used on a const char* of unknown origin while strtok cannot.它不像 strtok 那样修改字符串,这意味着它可以用于未知来源的const char*而 strtok 不能。 The difference is begin / end are pointers to the original string chars, so aren't null terminated strings like strtok gives.区别在于begin / end是指向原始字符串字符的指针,因此不是像 strtok 给出的空终止字符串。 Of course this uses a static local so isn't thread safe.当然,这使用静态本地,因此不是线程安全的。

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

Output:输出:

'meow !'
''
''
'meow ?'
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

Reinventing the wheel is often a bad idea.重新发明轮子通常是个坏主意。 Learn to use implementation functions is also a good training.学会使用实现函数也是一种很好的训练。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM