0

I'm writing a simple code that will read in a series of characters which terminates upon reading in '\n' character/ typing enter. The code will also only read in a maximum of 50 characters. However, I am receiving errors when compiling, segmentation fault. I am unsure why the loop is not ending despite taking in '\n' character.

 #include <stdio.h>
 #include <ctype.h>
 #define MAX 50

 int main(void){
     char str[MAX] = "0";             //initialise 1st char for the loop
     int i;
     printf("Enter your sentence, at most 50 character: \n");
     for(i = 0; str[i] != '\n'; i++){          //terminates upon \n
        str[i] = getchar();
        putchar(str[i]);
     }
     return 0;
 }

However, I tried moving the loop condition into the loop itself and use the if-break combo, it works perfectly.

#include <stdio.h>
#include <ctype.h>
#define MAX 50

int main(void){
    char str[MAX] = "0";             //initialise 1st char for the loop
    int i;
    printf("Enter your sentence, at most 50 character: \n");
    for(i = 0;; i++){          //terminates upon \n
        str[i] = getchar();
        putchar(str[i]);
        if(str[i] == '\n')
        break;
    }

    return 0;
}

Can any pros please explain to me why is this so and how do I correct it? Thanks a lot in advance! :)

RESOLVED. I'm checking the wrong element in the array. LOL.

2 Answers2

1

Learn how for loop works.

The

for(expr1; expr2; expr3)  // lack of expr2 means 'forever'
    instr;

is equivalent to

expr1;
while(expr2)  // expr2 is replaced with 'true' if empty
{
    instr;
    expr3;
}

So in your case

for(i = 0; str[i] != '\n'; i++)

the test str[i] != '\n' is calculated after the increment i++, hence it tests the wrong element of the array – the one past the one just read!

Additionally, you do not check the length of input data, so if you enter an input line longer than 50 characters, your loop will try to store the tail of a line past the end of declared array, which triggers an Undefined Behavior.

EDIT

A simple way to fulfill both criteria is to do both tests:

char str[MAX];
int i;

// print the actual value of defined maximum
printf("Enter your sentence, at most %d character: \n", MAX);

for(i = 0; i < MAX; i++){  // test the length
    str[i] = getchar();
    if(str[i] == '\n')     // test the input char
        break;
    putchar(str[i]);
 }
CiaPan
  • 9,381
  • 2
  • 21
  • 35
1

This happens because in the first case after str[i] = getchar(); ,the i++ statement executes before str[i] != '\n'; condition cheking . So the checking fails in your first code.

Try this modified for-loop:-

for(i = 0; (str[i] = getchar()) != '\n'; i++){     //Here checking happens while reading itself.
        putchar(str[i]);
     }

Remember that after the body of the for-loop executes, the flow of control jumps back up to the increment statement not to condition-cheking.

anoopknr
  • 3,177
  • 2
  • 23
  • 33