0

How do I get the index of the first non-whitespace character in a string. For example for the string " #$%abcd" I would expect getting the index 3 for #.

71GA
  • 1,132
  • 6
  • 36
  • 69
David King
  • 23
  • 1
  • 2
  • For some reason the white space in the string I wrote aren't showing in the question. – David King Apr 24 '17 at 16:08
  • Have a look at the C standard library functions for strings and characters. You will find the relevant functions in there. –  Apr 24 '17 at 16:09
  • 4
    Take a look at `strspn`. – Ry- Apr 24 '17 at 16:10
  • 2
    There's a function called `isspace()` in `ctype.h` that should come in useful. – r3mainer Apr 24 '17 at 16:11
  • @Ryan does this also work for C? I am asking because the page displayed is for C++. – 71GA Apr 24 '17 at 16:13
  • 1
    @71GA: Not sure what you mean by “page displayed”; I didn’t link to anything. `strspn` is a C function in `string.h`. – Ry- Apr 24 '17 at 16:17
  • Welcome to Stack Overflow! Please [edit] your question to show [the code you have so far](http://whathaveyoutried.com). You should include at least an outline (but preferably a [mcve]) of the code that you are having problems with, then we can try to help with the specific problem. You should also read [ask]. – Toby Speight Apr 24 '17 at 16:59

3 Answers3

2

Use strspn() to find the length of the whitespace and then skip past it.

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

const char whitespace[] = " \f\n\r\t\v";
char *str = "    Hello World!";

void main() {
    char *stripped = str + strspn(str, whitespace);
    printf("Stripped msg: '%s'", stripped);
}
4e554c4c
  • 478
  • 3
  • 12
1

Why not code it instead of include other libraries:
Here is a starting point:

int main () 
{
    char s[] = "   #$%abcd\0";
    size_t i = 0;
    while(s[i] == ' ' || s[i] == '\t'|| s[i] == '\n' || s[i] == '\r' || s[i] == '\f' || s[i] == '\v')
    {
        ++i;
    }
    return i;
}

i is the index of the first non-whitespace char:

GurstTavo
  • 336
  • 1
  • 3
  • 18
  • @Aconcagua, Yes, but then the library `#include ` must be included making it implementation specific, one small advantage of the implementation is the OR switch, I set the chars in order (IMHO) of probability of occurence in a "normal" text from left to rigth. – GurstTavo Apr 24 '17 at 17:24
  • @GurstTavo Curious you consider `s[i] == ' ' || s[i] == '\t'|| ...` an advantage over `isspace()`. `isspace()` is routinely a lookup into a table - no need for ordering in probability of occurrence. – chux - Reinstate Monica Apr 24 '17 at 17:47
  • 2
    `isspace()` is part of the standard library, so using it doesn't make the code all that implementation specific. And ctype.h is just a header not a library... you're most likely already linking to the library it goes with, and won't really add much extra code to the executable by using a function from it. – Dmitri Apr 24 '17 at 18:04
  • 1
    @chux, Yes, you are rigth, but still not sure if two dereferences (in the implementation I'm looking at) are better or worse than the 6 (worst case) comparisons OR switched. Maybe a runnig a profile tool may help, just for couriosity. – GurstTavo Apr 24 '17 at 20:09
  • 1
    @Dmitri, Thanks I checked and `isspace()` is declared in `ctype.h`, but after a short test the code compiles w/o any header including the `isspace()` function call. Also I'm confused about the definition of **library**. Yes `ctype.h` is a header, but also `stdlib.h` is a header. both implement functionality and macros. – GurstTavo Apr 24 '17 at 20:14
  • 3
    Header files usually *don't* implement functionality (aside from macros and inline functions, sometimes)... they merely provide declarations for functions and objects implemented elsewhere. http://stackoverflow.com/questions/924485/whats-the-difference-between-a-header-file-and-a-library – Dmitri Apr 24 '17 at 20:35
0

Old school:

const char *ptr;
for (ptr=str; *ptr && ((unsigned char)*ptr) <= ' '; ++ptr);
return (*ptr ? ptr-str : -1);
Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • 2
    This does make some assumptions about the character set... but it should work for ASCII, provided all control characters are to be treated as whitespace. `isspace((unsigned char)*ptr)` may be better than `((unsigned char)*ptr) <= ' '`. – Dmitri Apr 24 '17 at 17:07
  • isspace is locale-sensitive. OK if that's what you want... If it's not, then what characters do you really want to skip? <=' ' is fast and skips an acceptable char set for must uses. – Matt Timmermans Apr 25 '17 at 02:34