2

I have a string like this:

char* hello = "Hello, world!";

And I have to loop through every character in this string. I tried these, but they either give me compile error, or access violation, or just never leave loop:

for( char* p = hello; p!=0; p++ ) printf("%x\n", p);

for( char* p = &hello; p!=0; p++ ) printf("%x\n", p);

for( char* p = *hello; p!=0; p++ ) printf("%x\n", p);

for( char* p = hello; *p!=0; *p++ ) printf("%x\n", *p);

I don't really understand how pointers work in C, I'm just placing asterisk randomly until it works, and in this case it doesn't.

I don't use strlen like that other question.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
Peret Finctor
  • 192
  • 1
  • 7
  • 4
    If you don't understand pointers, please read a tutorial. Stack Overflow cannot replace a tutorial. – fuz Dec 23 '15 at 00:08
  • 2
    Then maybe you need to read-up on pointers first: http://www.praxagora.com/doc_model/understanding_c_pointers_1.0.html – OldProgrammer Dec 23 '15 at 00:08
  • Possible duplicate of [How to iterate over a string in C?](http://stackoverflow.com/questions/3213827/how-to-iterate-over-a-string-in-c) – MaxOvrdrv Dec 23 '15 at 00:09
  • @FUZxxl maybe you know about a good collection of examples of working with pointers? – Peret Finctor Dec 23 '15 at 00:22
  • 1
    @PeretFinctor Only in German, sorry. But [this video](https://www.youtube.com/watch?v=6pmWojisM_E) might be somewhat enlighting. – fuz Dec 23 '15 at 00:28
  • regarding this line: `for( char* p = hello; p!=0; p++ ) printf("%x\n", p);` it is 'almost' correct. 1) the pointer `p` will not be 0 until it overflows, However, where it points will contain a '\0' at the end of the string. 2) the 'p' in the printf() statement is a pointer to 'the rest of' the string. I suspect you only want to print a single byte, in hex. Suggest: `for( char* p = hello; *p; p++ ) printf("%x\n", p[0]);` where '*p' means where p points so will exit the for loop when at the NUL byte at the end of the string. Where 'p[0]' is the single byte currently pointed at by 'p' – user3629249 Dec 23 '15 at 00:40
  • Your fourth option is correct if you're on an ASCII system (likely) , you will get the ascii codes of each character in the string printed. – M.M Dec 23 '15 at 00:46
  • @user3629249 `p` will never compare equal to zero (Unless the program has already triggered undefined behaviour, of course) – M.M Dec 23 '15 at 00:47
  • @user3629249 I was responding to your claim "the pointer p will not be 0 until it overflows" – M.M Dec 23 '15 at 00:51
  • @M.M, 'p' is a pointer, there are no negative pointers (a negative value will just wrap around memory as if it were a very large positive value % max memory address.) – user3629249 Dec 23 '15 at 01:00
  • The stuff you put in brackets isn't true . Maybe you describe some manifestation of undefined behaviour on some particular system. – M.M Dec 23 '15 at 01:01

2 Answers2

5

p is a pointer to char. Therefore, dereferencing it with *p yields a char.

Adding 1 to p moves it to the next character in whatever string you’re traversing. Adding 1 to *p adds one to the character p is pointing to.

Let’s go through each of your tries and see what’s wrong with it.

char* hello = "Hello, world!";

The common part: hello is a pointer to char, and it is pointing to a constant string that the compiler will embed somewhere in the object file. Note that such a string should not be changed; you will often get an error for doing so.

If you want a string you can change, char hello[] = "Hello, world!"; works; this creates a buffer as a local variable that can be freely manipulated.

for( char* p = hello; p!=0; p++ ) printf("%x\n", p);

Here, you correctly point p at the first character of hello. However, you then look for the end of the string by comparing p to zero. p is a pointer, and 0 as a pointer means a NULL pointer.

for( char* p = &hello; p!=0; p++ ) printf("%x\n", p);

Here, you point p at the address of hello, meaning wherever the process is storing the pointer known as hello. Dereferencing this will give you hello, not what it points to.

for( char* p = *hello; p!=0; p++ ) printf("%x\n", p);

Here, you dereference hello, giving a char with a value of H. Assigning this to p is a type mismatch and semantically incorrect as well.

for( char* p = hello; *p!=0; *p++ ) printf("%x\n", *p);

Here, at last, you correctly compare what p points to, to zero. However, you also increment *p instead of p, which is incorrect, and also (as mentioned above) will cause problems with a constant string such as this one. *p++ will increment p as well, returning what p pointed to before the increment, which is moot since it isn’t used.

One other thing: do you want to print the value of the pointer p, or the char it’s pointing to? The first three print the pointer correctly. The last one uses %x to print the char. Not sure what that will do, but it won’t be correct.

Since you used %x, I assume you want to print the character itself in hex? That would be printf("%x\n", *p); as in the last one. However, I would recommend %02x to get a constant width with zero-padding.

Assuming you want to print the character, here’s a correct version:

for( char* p = hello; *p!=0; p++ ) printf("%x\n", *p);

Or, since 0 is false, we can say more briefly and idiomatically:

for( char* p = hello; *p; p++ ) printf("%x\n", *p);
Tom Zych
  • 13,329
  • 9
  • 36
  • 53
3

None of them.

The answer is : for( char* p = hello; *p !=0; p++ ) printf("%x\n", *p);

char *p = hello; // p is pointing on the first case of hello, it's exactly the same as char *p = &hello[0];

if(*p == 0) // check if *p == '\0' ('\0' == 0 in ASCII, which means end of string). *p is the value of the adress pointed per p.

'p++' // increase p of sizeof(char) ( so it's += 1). With that you are on the adresse of hello[1] then hello[2] etc...

  • well, not quite. in the second parameter of the 'for()' statement, this is comparing a single byte '\0' to the (4 or 8 bytes) integer 0. in the 'printf()' statement the 'p' is the address contained in 'p' However a pointer is properly printed with a '%p' not a '%x'; but the OP wants to print the char pointed to by 'p' in a hex format, so it should be: 'p[0]' – user3629249 Dec 23 '15 at 00:44
  • @user3629249 What do you know about implicit conversions? – user253751 Dec 23 '15 at 00:45
  • And yes, this should be `printf("%c\n", c);` to print the characters (as opposed to the address of each character) – user253751 Dec 23 '15 at 00:46
  • I know a massive lot about implicit conversions. I also know that the OP doesn't know, so the suggest answer is misleading the OP. – user3629249 Dec 23 '15 at 00:47
  • %x = hexadecimal representation. Failed, forgot to put *p in the printf. – Pierre Emmanuel Lallemant Dec 23 '15 at 00:48
  • `printf("%x\n", *p);` will cause undefined behaviour if any of the characters in the string have negative character codes – M.M Dec 23 '15 at 00:48
  • he is using the 1st ASCII table, good luck to find a negative value. – Pierre Emmanuel Lallemant Dec 23 '15 at 00:49
  • `%x` will not print the address of each character, just the hex representation of it. I'm sure that's what you meant, but just being explicitly clear. – Turn Dec 23 '15 at 00:49