0

So in the following code, I want to store each section in the corresponding variable. Is there an easier way to do this rather than looping through the entire string char by char and checking if it's equal to \0 or not?

int main()
{
    char *test = "Hello My\0friends\0I love food!";
    
    char *section1; // Hello My
    char *section2; // friends
    char *section3; // I love food!

    return 0;
}
  • 2
    If a string is containing `\0` in it anywhere but its end, then it is not a string in terms of C. – Eugene Sh. Nov 23 '21 at 21:06
  • Assign the addresses of the first char of the subtext: `char *section1 = test; char *section2 = &test[9]; char *section3 = &test[17]`. – 001 Nov 23 '21 at 21:06
  • In this case iteration would work since you know how many strings there are. It would be more difficult if you did not: how would you know when to stop looking without some marker? Like maybe an extra `\0` at the end. – 001 Nov 23 '21 at 21:11
  • I fact one can use `strlen` – Eugene Sh. Nov 23 '21 at 21:12
  • Question more correct as "how do I extract the different parts of a _string literal_ that are all separated by the \0 null terminator?". A _string_ ends at the first `'\0'`. – chux - Reinstate Monica Nov 23 '21 at 21:20
  • @chux-ReinstateMonica Or more generally - array of `char`. – Eugene Sh. Nov 23 '21 at 21:25
  • @EugeneSh. If we have an _array of char_ then that supposes the last `char` may differ from `'\0'`. OP goal relies on the _array of char_ or _string literal_ having 3+ _null characters_ and likely wants it to end with the 3rd null character.. Unclear what OP would want with `char a[] = { 'a', 0, 'b', 0, 'c', 0, 'd' }`. – chux - Reinstate Monica Nov 23 '21 at 21:31
  • *Is there an easier way to do this rather than looping through the entire string char by char?* Is there a way that''s easier on you, or on the computer? *Somebody* is going to have to step through that array, one character at a time, looking for embedded `\0` characters. You can write code involving `const char *p` and `*p++` to do that yourself, or you can use standard library functions such as `strlen` or `strchr` or `strrchr` to do it for you, but somewhere, there's going to be a loop stepping through the array one character at a time. – Steve Summit Nov 23 '21 at 22:26
  • See also [How does the function Strrchr find the last c if c == '\0'?](https://stackoverflow.com/questions/69930229/how-does-the-function-strrchr-finds-the-last-c-if-c-0) – Steve Summit Nov 23 '21 at 22:29
  • If you want to do this sort of thing, I recommend using `char *test = "Hello My\0friends\0I love food!\0";` so that you can look for two `\0`'s in a row to unambiguously indicate the end of your sequence of strings. – Steve Summit Nov 23 '21 at 22:31

2 Answers2

4

You have a character array containing multiple strings.

section1 = test;
section2 = test + strlen(test) +1;
section3 = section2 + strlen(section2) + 1;
stark
  • 12,615
  • 3
  • 33
  • 50
2

This works:

const char * test = "Hello My\0friends\0I love food!";
const char * section1 = test;
const char * section2 = strchr(section1, 0) + 1;
const char * section3 = strchr(section2, 0) + 1;

Also, note that the section variables are just pointers into the test string. That's fine if you are defining test the way I did above, but if you are defining test in some other more complicated way, you need to make sure the test string does not get deallocated or modified, or you need to make copies of the section strings before that happens.

Don't forget to include string.h at the top of your program.

However, I'd like to add that if you didn't know about the strchr function, it should be trivial to implement it yourself by writing a loop that iterates through the string and looks for a null character and returns the pointer to it.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • 1
    Does `strrchr` really work with `\0` ? Is it guaranteed to work? Looks like you can use `strlen` instead. – Eugene Sh. Nov 23 '21 at 21:12
  • amazing, thnak you! – Jorge Jones Nov 23 '21 at 21:13
  • Using `strchr` (or `strlen`) seems more sensible than `strrchr`. Although `strrchr` might work, it's much less obvious whether it does. – jamesdlin Nov 23 '21 at 21:14
  • Oh yeah, `strchr` makes more sense, since it returns the first occurence instead of the last occurence. Both functions should be fine, since the standard explicitly says they support finding a pointer to the null terminator character. – David Grayson Nov 23 '21 at 21:16
  • 2
    In C, string literals are not `const` qualified; the pointer that results from the automatic conversion of an array to a pointer has type `char *`, not `const char *`. (In C++, they are `const`.) – Eric Postpischil Nov 23 '21 at 21:21
  • Indeed, it *is* guaranteed to work as per *"The strchr function locates the first occurrence of c (converted to a char) in the string pointed to by s. **The terminating null character is considered to be part of the string**."* – Eugene Sh. Nov 23 '21 at 21:23
  • For those wondering, `strrchr` is guaranteed to work also. We [covered this a few days ago](https://stackoverflow.com/questions/69930229). – Steve Summit Nov 23 '21 at 22:29
  • A string literal is an "array of static storage duration" (6.4.5 para 6), so there's no need to make a copy. As Eric says, it's element type is `char`, not `const char`, but that's not an invitation; any attempt to modify the contents of a string literal is undefined behaviour (q.v.) so you should treat it as though it were immutable. – rici Nov 24 '21 at 01:39