Home > Software design >  how to extract all tokens include null value from a string in C
how to extract all tokens include null value from a string in C

Time:11-15

Below code uses strtok function to extract tokens from string by delimeter ','.

ex.

#include<stdio.h>
#include <string.h>

int main() {
   char string[200] = "$GNGNS,103600.01,5114.51176,N,00012.29380,W,45.6,,,V*00";
   // Extract the first token
   char * token = strtok(string, ",");
   // loop through the string to extract all other tokens
   while( token != NULL ) {
      printf( " %s\n", token ); //printing each token
      token = strtok(NULL, ",");
   }
   return 0;
}

The output is

 $GNGNS
 103600.01
 5114.51176
 N
 00012.29380
 W
 45.6
 V*00

Here the null value ,,, between 45.6 and V*00 are ignored. How can I print all tokens eventhrough it is null? like:

$GNGNS
103600.01
5114.51176
N
00012.29380
W   
45.6


V*00

CodePudding user response:

The function strtok does not consider an empty token to be a valid token. However, you can easily solve the problem using strchr instead of strtok:

#include <stdio.h>
#include <string.h>

int main()
{
    const char *const string =
        "$GNGNS,103600.01,5114.51176,N,00012.29380,W,45.6,,,V*00";

    const char *p = string, *q;

    //continue looping until there are no more ',' characters
    while ( ( q = strchr( p, ',' ) ) != NULL )
    {
        //print token
        printf( "%.*s\n", (int)(q-p), p );

        //make p point one character past the ',', which is the
        //first character of the next token, unless the next
        //token is empty
        p = q   1;
    }

    //print last token
    printf( "%s\n", p );
}

Output of program:

$GNGNS
103600.01
5114.51176
N
00012.29380
W
45.6


V*00

This solution also has the advantage that the string is allowed to be read-only. Therefore, I was able to define the string as a string literal instead of an array (I didn't have to, though). This would not have been possible with strtok, because that function is destructive in the sense that it overwrites the delimiters with null terminating characters, which requires the string to be writable.

CodePudding user response:

I would write something simple instead of strtok.

char **split(char **argv, int *argc, char *string, const char delimiter, int allowempty)
{
    *argc = 0;
    do
    {
        if(*string && (*string != delimiter || allowempty))
        {
            argv[(*argc)  ] = string;
        }
        while(*string && *string != delimiter) string  ;
        if(*string) *string   = 0;
        if(!allowempty) 
            while(*string && *string == delimiter) string  ;
    }while(*string);
    return argv;
}

int main() {
   char string[200] = "$GNGNS,103600.01,5114.51176,N,00012.29380,W,45.6,,,V*00";

    char *args[20];
    int nargs;

    split(args, &nargs, string, ',', 1);

    for(int x = 0; x < nargs; x  )
    {
        printf("ARG[-] = `%s`\n", x, args[x]);
    }

   return 0;
}

https://godbolt.org/z/vKqP4hvG4

Output:

ARG[ 0] = `$GNGNS`
ARG[ 1] = `103600.01`
ARG[ 2] = `5114.51176`
ARG[ 3] = `N`
ARG[ 4] = `00012.29380`
ARG[ 5] = `W`
ARG[ 6] = `45.6`
ARG[ 7] = ``
ARG[ 8] = ``
ARG[ 9] = `V*00`
  •  Tags:  
  • c
  • Related