-3

I am using C90, and I want to read a string that looks something like this:

str = "          INFO       INFO        INFO INFO"

INFO is a word without white spaces in it. I want to know, what is the best way to read the first INFO word?

The problem is that there could be any number (up to 166) of whitespace characters before the INFO, but a white space character is also what marks the end of the INFO word. So I need to ignore the whitespaces before it, but stop reading at a white space after it.

Is there a function that can do it? Or do I need to write it myself?

And if I write it myself, do I actually need an if statement that looks like "character != '\t' && character != " " && character != ...."? or there is a way to tell the language x == whitespace?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

2 Answers2

1

what is the best way to read the first INFO word?
is there a function that can do it?

Funny enough there is.

char info1[20]; // some constant size buffer
if (sscanf(str, "%19s", info1) != 1) {
     /* handle error */
}

do I actually need an if statemant that looks like "character != '\t' && character != " " && character != ...." ?

There is strchr and strspn functions. You could just:

 const char * const whitespace = " \f\n\r\t\v";
 const char * const first_word = str + strspn(str, whitespace);
 const size_t len_of_first_word = strcspn(first_word, whitespace);
 printf("%.*s", (int)len_of_first_word, first_word);
 // TODO: add error checking.
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • There's also `isspace()` — or maybe `isblank()`, though not in C90 — from ``. – Jonathan Leffler Aug 10 '20 at 23:56
  • If the problem includes reading all the words with a loop, see [Using `sscanf()` in a loop](https://stackoverflow.com/questions/3975236/how-to-use-sscanf-in-loops) for how to know where to start processing for subsequent words in the string. – Jonathan Leffler Aug 10 '20 at 23:58
0

When you learn is good to write it yourself even in the simplest form. Here you have an example

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

char *mystrchr(const char *str, char ch)
{
    if(str)
    {
        while(*str)
        {
            if(*str == ch) break;
            str++;
        }
    }
    return  (str && *str) ? (char *)str : NULL;
}

void freetok(char **argv, size_t size)
{
    if(argv)
    {
        for(size_t token = 0; token < size; token++)
        {
            free(argv[token]);
        }
        free(argv);
    }
}



char **mytok(const char *src, size_t *argc, const char *separators)
{
    char **argv = NULL;
    char **tmp;
    const char *tokenstart;

    *argc = 0;
    if(src)
    {
        do
        {
            while(mystrchr(separators, *src)) src++;
            if(*src)
            {
                tmp = realloc(argv, (*argc + 1) * sizeof(argv));
                if(!tmp) 
                {
                    goto cleanup;
                }
                argv = tmp;
                tokenstart = src;
                while(*src && !mystrchr(separators, *src)) src++;
                argv[*argc] = malloc(src - tokenstart + 1);
                if(!argv[*argc])
                {
                    goto cleanup;
                }
                memcpy(argv[*argc], tokenstart, src - tokenstart);
                argv[(*argc)++][src - tokenstart] = 0;
            }
        }while(*src);
    }

    return argv;

    cleanup:
    freetok(argv, *argc);
    *argc = (ssize_t)-1;
    return NULL;
}


int main(void)
{
    char *x = "          INFO  ,,     INFO1        INFO2 INFO3   ";
    size_t ntokens;
    char **tokens = mytok(x, &ntokens, " ,");

    for(size_t token = 0; token < ntokens; token++)
        printf("token np %2zu = \"%s\"\n", token, tokens[token]);
    freetok(tokens, ntokens);
}
0___________
  • 60,014
  • 4
  • 34
  • 74