1

I am learning C. In the following code why does replacing "*ptr_str" with "ptr_str[i]" in the for loop truncate?

/* 13L01.c: Initializing strings */
#include <stdio.h>
main()
{
 char str1[] = {'A', ' ',
 's', 't', 'r', 'i', 'n', 'g', ' ',
 'c', 'o', 'n', 's', 't', 'a', 'n', 't', '\0'};
  char str2[] = "Another string constant";
  char *ptr_str;
  int i;

  /* print out str2 */
  for (i=0; str1[i]; i++)
      printf("%c", str1[i]);
      printf("\n");
  /* print out str2 */
  for (i=0; str2[i]; i++)
      printf("%c", str2[i]);
      printf("\n");
   /* assign a string to a pointer */
   ptr_str = "Assign a strings to a pointer.";
   for (i=0; *ptr_str; i++)
       printf("%c", *ptr_str++);
   return 0;

}

3 Answers 3

2
   // A, ok
   while (*ptr_str)
       printf("%c", *ptr_str++);

   // B, also ok
   for (i=0; ptr_str[i]; i++)
       printf("%c", ptr_str[i]);

   // C, works but ugly
   for (i=0; *ptr_str; i++)
       printf("%c", *ptr_str++);

C is your form, it is flawed because i is doing nothing here, so A is an improved version. If you want to use i, do it like B. If you use both i and ptr_str, and increment both of them in the loop, nothing good will happen. Increment one or the other.

Sign up to request clarification or add additional context in comments.

5 Comments

I answered, then reread your answer and figured out that you had already answered it, just with fewer words. So +1
@gmiket Truncation is absolutely not a necessary consequence of prt_str[i] as the test in the for loop. See my B) snippet, which works fine.
@Chris, thanks your answer is good too, so +1 for you from me too!
// C, works but ugly for (i=0; *ptr_str; i++) printf("%c", *ptr_str++;); seems to me a pointless construction. Why not just for (; *ptr_str;) printf("%c", *ptr_str++);
@gmiket I agree it's a pointless contruction, I only mentioned it because that is the code you posted !!!! Your suggestion of for (; *ptr_str;) printf("%c", *ptr_str++); is just a slightly uglier version of my while (*ptr_str) printf("%c", *ptr_str++); Both are fine and will work.
2

Because you're advancing ptr_str and then treating it as an array and testing if it's pointing to NULL on the i'th member. You're basically testing if ptr_str[i+i] is NULL instead of ptr_str[i].

4 Comments

ASCII NUL ('\0') is not NULL ((void *)0).
@Chris: NULL is not necessarily (void*)0 it may be 0 or 0L or equivalent even in plain C.
@Jens - I know, but @kichik wants the NUL character, which is '\0'. Even if using NULL might compile and work, it's still important to differentiate the two (especially to beginners).
@Chris: Sure. Just wanted to state the "real" value of NULL, namely that there isn't :) at least nothing reliable.
1

Your question is a bit unclear, but I think I've got it:

In the following code why does replacing "*ptr_str" with "ptr_str[i]" in the for loop truncate?

I think you mean changing this:

for (i=0; *ptr_str; i++)
    printf("%c", *ptr_str++);
return 0;

to this:

for (i=0; ptr_str[i]; i++)
    printf("%c", *ptr_str++);
return 0;

The second one truncates because you're advancing i and ptr_str, so the modified starting position of ptr_str plus the modified starting position of i ends up cutting you off too soon (or worse, having an odd number of characters and overflowing into data that isn't yours). The second example that truncates is equivalent to:

for (i=0; ptr_str[i * 2]; i++)
    printf("%c", ptr_str[i]);
return 0;

Now do you see why it truncates?

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.