1

I am trying to print all the 4 strings in the given program. But I am unable to print the strings. With the code below I get some weird output.

int main()
{
    char szStr[] = "India\0Japan\0America\0Australia";
    char *p = szStr;

    while(p)
    {
        printf("%c", p);
        p++;
    }

    return 0;
} 
9
  • 1
    Which kind of weird output? Try also ending "Australia" with the string terminator "\0" Commented Aug 8, 2013 at 13:08
  • Why are you complicating your life? Commented Aug 8, 2013 at 13:10
  • 1
    Your loop will never end. Commented Aug 8, 2013 at 13:11
  • 3
    @Vik What? In a string literal, that's included automatically! Commented Aug 8, 2013 at 13:11
  • 1
    Do you need to have them all in one string literal like that? The normal approach would be to use an array of strings like char * szStr[] = {"India", "Japan", "America", "Australia"};. Then use %s in the printf, not %c. And you'll need a different way of knowing when to stop. Commented Aug 8, 2013 at 13:12

5 Answers 5

4
while(p)

is the same as

while(p != NULL)

which is of course always true - the string literal points to a valid memory location. I feel you are confusing this with

while(*p)

or with the equivalent

while(*p != 0)

because that would run until it finds the 0-terminator in the string. That's not good enough either, though. You don't know which string you just printed. You have to keep track of the number of strings manually. Also, why print it character-by-character, invoking the quite expensive printf() function for every byte you display? It's just wasteful. How about something like

char szStr[] = "India\0Japan\0America\0Australia";

char *p = szStr;

for (int i = 0; i < 4; i++) {
    puts(p);
    p += strlen(p) + 1;
}

Still, I don't see why this is simpler or otherwise better than simply storing an array of strings. Like this:

const char *strings[] = {
    "India",
    "Japan",
    "America",
    "Australia"
};

for (int i = 0; i < sizeof(strings) / sizeof(strings[0]); i++)
    puts(strings[i]);
Sign up to request clarification or add additional context in comments.

Comments

2

This is tested and works:

#include <stdio.h>

int main()
{
    char szStr[] = "India\0Japan\0America\0Australia\0";
    char *p = szStr;

    while(*p)
    {
        p += printf("%s", p);
        p++;
        fputc('\n', stdout);
    }

    return 0;
}

Note the extra null-terminator on the string. This is actually important, despite the fact that the string literal has it's own null-term. The double null-term is necessary to terminate the while loop correctly.

Explanation:

printf returns the number of characters written, i.e., the length of each string, not including the null terminator. So when you add this to p, you're left with p pointing at the null-terminator. Increment p again and you're at the start of the next string. If that string is length-0, then p is once again pointing to a null-terminator, so the while loop will bail. That's why you need the extra null-terminator on the end of the string.

6 Comments

Clever, but for extra safety and readability, I'd separate the p += printf("%s", p); statement in two statements. You know, it's not obvious where/if there are sequence points, and we better avoid UB.
Could whoever downvoted explain why so I can improve it? thanks.
@H2CO3: Not sure what you mean by sequence points or UB. Could you explain? Modify-assigment operators (like +=) are always contentious: some people think they're too cryptic or subtle, but I prefer them over introducing variables that are only used once. Just a matter of coding style.
I happen to be one of the people you are talking about. It's not that I don't understand what the code does, I just don't want to have to think about it fore more than a quarter of a second.
@sh1fts0rm - It's not the += operator I'm concerned with. It's the way you used it. p += printf("%s", p) can falsely suggest that p is being modified while printed. But don't take me wrong, I'm not saying that your code is wrong by any means... I just noticed this subtlety.
|
0

%c is format specifier for printing a single character. Use %s instead. Still printf will only print the string up to the first \0 character. You will have to perform some kind of split before printing if you want the four strings to be output. Maybe use sscanf with "%s%s%s%s".

2 Comments

True but not sufficient for what the OP wants. The will just print each suffix of the first string "India."
Eh, it's still not much of an answer. More of a hint.
0

Change the line while(p) to while(*p).

In c, anything other than 0 will be considered true and 0 will be considered false.

So, p is not 0 and it makes the while loop repeat ever and ever again.

But *p will become 0 at the end of the string.

1 Comment

That will only print every suffix of the first string "India". The OP wants to print each string embedded in the character array.
0

Remember that *p gets you the value pointed by p.

This will work:

int main()
{
    char szStr[] = "India\0Japan\0America\0Australia\0";
    char *p = szStr;
    int numOfStrings = 4;
    for(int i = 0; i < numOfStrings; i++)
    {
        while(*p)
        {
            printf("%c", *p);
            p++;
        }
        printf(" "); //print a space character to separate your strings
        p++; //advance pointer to skip '\0' between strings
    }    
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.