简体   繁体   中英

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. I was thinking to use a delimnator but i dont know how to do it in 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.

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 . 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" . The <handle error> is a place-holder for code to react to missing delimiters.

Note that, like strtok , the original string is modified by replacing the delimiters with NULLs.

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. The difference is begin / end are pointers to the original string chars, so aren't null terminated strings like strtok gives. 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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