2

I am not able to find out the reason for the misbehavior of the below code. This is a simple code to accept characters until either * is entered or until array size is reached and then print the characters read from the keyboard. It looks like the reading part is fine. Also if I enter * before array size is reached everything is OK. But if I do not enter * and wait until array size is reached in reading portion, I have the trouble. While printing it prints the characters read, but after that some garbage is printed. Ran through debugger, but while loop is not breaking when index is 3 or more.

int main()
{
    char myStr [3];
    unsigned int index=0;
    printf("Enter Single characters. Enter * to stop\n");
    do
    {
        scanf(" %c",&myStr[index]);
        index++;
    } while ((myStr[index-1]!='*')&&((index)<(sizeof(myStr)/sizeof(myStr[0]))));

    index=0;

    while ((myStr[index]!='*')&&(index<(sizeof(myStr)/sizeof(myStr[0]))))
   {
        printf("%c",myStr[index]);
        index++;
    }
    printf("\n");

    return(0);
}
alk
  • 69,737
  • 10
  • 105
  • 255
Rajesh
  • 1,085
  • 1
  • 12
  • 25
  • Sizeof mystr is fixed by declaring it [3], perhaps? In that case your quotient would not represent the number of actual chars in the array? – Jeremy Kahan Nov 06 '16 at 12:02
  • @JeremyKahan: Doing `sizeof(myStr)/sizeof(myStr[0])` on an array is perfectly valid to calculate the numbers of elements. – alk Nov 06 '16 at 12:03
  • @alk yes, but I was worried that there are three elements whether or not the user entered three. But I see now that it should not matter, since either the user enters the star or must enter three. – Jeremy Kahan Nov 06 '16 at 12:16
  • Note: You can simplify your loop logic by using for() loops. – wildplasser Nov 06 '16 at 12:59

2 Answers2

2

The code runs into undefined behaviour on the printf loop's last iteration here

    while ((myStr[index]!='*')&&(index<(sizeof(myStr)/sizeof(myStr[0]))))
    {
      ...

as it in fact is doing

    while ((myStr[3] ....

with myStr[3] accessing myStr out-of-bounds.

To fix this do:

    while ((index < (sizeof(myStr)/sizeof(myStr[0]))) && (myStr[index] != '*'))

Boolean short-circuiting will take care of myStr[3] not being executed.

alk
  • 69,737
  • 10
  • 105
  • 255
  • Thank you for your good analysis. Coming to undefined behavior of out-of-bound values: I understand that myStr[4] could be garbage value. But still it should have some value (I thought ) because it is pointing to some memory location for sure. In such case first part may evaluate to TRUE or FALSE. In such case code should have behaved correctly. But I never knew that just reading a memory that is not significant could result in total misbehavior of the application. I can understand the undefined behavior of the system if I write to a memory that is out of bound. – Rajesh Nov 06 '16 at 14:29
  • To clarify: When index=3 while loop anyway will not enter because second part becomes FALSE. So printf() does not come into picture right? – Rajesh Nov 06 '16 at 14:40
  • Fixed the indexing from 4 to 3 ... :} – alk Nov 06 '16 at 14:47
0

You are manipulating strings, witch need to be null-terminated. You should use fgets(3) to get your string and then strlen(3) to get the length. Then you can move in your string by while (str[i] != '*' && i < strlen(str)) good luck

Glick
  • 111
  • 7
  • 2
    "*You are manipulating strings ...*" no, the OP uses a `char`-array, that's all. There are no C-"strings" around, nor any functions relying on the `char`-arrays being used as a C-"string". – alk Nov 06 '16 at 11:57
  • My bad, i saw a char* – Glick Nov 06 '16 at 12:10
  • How would a pointer to a `char` (a `char*`) change something? – alk Nov 06 '16 at 16:21