47

Is there a C library function that will return the index of a character in a string?

So far, all I've found are functions like strstr that will return the found char *, not it's location in the original string.

Ryan Ahearn
  • 7,886
  • 7
  • 51
  • 56

7 Answers7

39

strstr returns a pointer to the found character, so you could use pointer arithmetic: (Note: this code not tested for its ability to compile, it's one step away from pseudocode.)

char * source = "test string";         /* assume source address is */
                                       /* 0x10 for example */
char * found = strstr( source, "in" ); /* should return 0x18 */
if (found != NULL)                     /* strstr returns NULL if item not found */
{
  int index = found - source;          /* index is 8 */
                                       /* source[8] gets you "i" */
}
Bill
  • 14,257
  • 4
  • 43
  • 55
  • 4
    Undefined behavior if the character is not found. Also you should not use `strstr` (with or without the typo) if `strchr` would suffice. – R.. GitHub STOP HELPING ICE Oct 24 '10 at 04:51
  • @R.. - I fixed the typo and added error checking to the pseudocode. Also, `strchr` does not work for finding multi-character sequences, does it? – Bill Oct 24 '10 at 23:35
  • 2
    Indeed, but OP asked for a character not a substring. Of course if you interpret character broadly to include multibyte characters, `strstr` is the right function to use. – R.. GitHub STOP HELPING ICE Oct 25 '10 at 00:33
  • @R.. - Since the OP was talking about a character as in text, not as in the `char` storage name, I gave a solution that has a hope of working for a character like 輪. You object? – Bill Oct 25 '10 at 03:30
16

I think that

size_t strcspn ( const char * str1, const char * str2 );

is what you want. Here is an example pulled from here:

/* strcspn example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "fcba73";
  char keys[] = "1234567890";
  int i;
  i = strcspn (str,keys);
  printf ("The first number in str is at position %d.\n",i+1);
  return 0;
}
Jonathan Works
  • 1,826
  • 1
  • 17
  • 13
  • 13
    `strcspn` is more like `String.IndexOfAny()` - searching for any of the characters in the `keys` array. But yeah, it'll do the trick – Isak Savo Mar 19 '10 at 06:25
  • 2
    The above comment is very important - doing it as in the example DOES NOT mimic indexOf(), so the original answer is pretty much incorrect. – GreenieMeanie Nov 15 '11 at 16:59
  • 2
    This is exactily what you are looking for: http://stackoverflow.com/a/1479401/3395760 – Alessandro Muzzi Jun 14 '16 at 23:08
  • Updated [here](https://cplusplus.com/reference/cstring/strcspn/?kw=strcspn) link in case anyone wants it ... – Ed Graham Mar 10 '23 at 17:45
14

EDIT: strchr is better only for one char. Pointer aritmetics says "Hellow!":

char *pos = strchr (myString, '#');
int pos = pos ? pos - myString : -1;

Important: strchr () returns NULL if no string is found

Michal Sznajder
  • 9,338
  • 4
  • 44
  • 62
  • You might want to rewrite the second line as `int ipos = pos ? pos - myString : -1;` to avoid compiler errors - but otherwise this still works in 2023! – Ed Graham Mar 10 '23 at 17:59
4

You can use strstr to accomplish what you want. Example:

char *a = "Hello World!";
char *b = strstr(a, "World");

int position = b - a;

printf("the offset is %i\n", position);

This produces the result:

the offset is 6
Kyle Cronin
  • 77,653
  • 43
  • 148
  • 164
0

Write your own :)

Code from a BSD licensed string processing library for C, called zString

https://github.com/fnoyanisi/zString

int zstring_search_chr(char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}
fnisi
  • 1,181
  • 1
  • 14
  • 24
0

You can write

s="bvbrburbhlkvp";
int index=strstr(&s,"h")-&s;

to find the index of 'h' in the given garble.

klutt
  • 30,332
  • 17
  • 55
  • 95
0

If you are not totally tied to pure C and can use string.h there is strchr() See here

Adam Haile
  • 30,705
  • 58
  • 191
  • 286