1

I was writing a code to print all the strings stored in 2d array after the user has finished typing the strings along with mentioning the maxlength of each string and total number strings (it will finally print the string along with the line number). The problem is that the code actually stores all the strings in the 2d array with one whole line of spacing i.e, one full empty row. The code, expected output and the output it is giving is below.

Code:

#include <stdio.h>

int main() {
    char s[20][30];
    int i, number_of_strings, length_of_string, j = 0;
    scanf("%d %d", &number_of_strings, &length_of_string);

    for (i = 0; i<number_of_strings; i++) {
        while ((s[i][j++] = getchar()) != '\n' && j<length_of_string)
            s[i][j] = '\0';
        j = 0;
    }

    for (i = 0; i<number_of_strings; i++) {
        printf("i= %d   %s\n", i, s[i]);
    }

    return 0;
}

Sample Input:

2 3
raj
jar

Expected Output:

i= 0   raj
i= 1   jar 

Output giving:

i= 0   

i= 1   raj
i= 2    

i= 3   jar

Please rectify where am I doing mistake.

14
  • 1
    Do you realize you have a newline stuck in your input buffer after you second int read ? what do you suppose that does to your first loop iteration ? Commented Nov 12, 2018 at 8:02
  • 1
    You need to eat the \n before it consumes in your next iteration. Commented Nov 12, 2018 at 8:04
  • 1
    scanf("%d %d", &number_of_strings, &length_of_string); leaves the \n of 2 3\n in the buffer and the first getchar() reads it. Commented Nov 12, 2018 at 8:04
  • 1
    while ((s[i][j++] = getchar()) != '\n' && j<length_of_string) s[i][j] = '\0'; ==> size test first as (j + 1) <length_of_string Commented Nov 12, 2018 at 8:04
  • 1
    @KaustavBhattacharjee \n is in your buffer. This is the problem. Commented Nov 12, 2018 at 8:06

1 Answer 1

1

You've hit one of the many issues with scanf. In this case scanf("%d %d", ...) is leaving a newline on the buffer. You can get it to slurp in trailing whitespace with a space on the end.

scanf("%d %d ", &number_of_strings , &length_of_string); 

Then how you're reading a line is complicated. You can simplify it like so:

 int c, j;
 for(j = 0; (c = getchar()) != '\n'; j++ ) {
     s[i][j] = (char)c;
 }
 s[i][j] = '\0';

Or even simpler...

for(int i=0 ; i<number_of_strings ; i++) {
    scanf("%29s", s[i]);
}

And there's no need for length_of_string. In fact, it's a liability since you've only allocated 30 bytes max. Similarly, number_of_strings can be higher than the allocated 20. It's better to read until input or memory is exhausted.

#include <stdio.h>

const int MAX_STRINGS = 20;
const int MAX_LENGTH = 30;
int main(){ 
    char s[MAX_STRINGS][MAX_LENGTH];
    int num_strings;
    for(num_strings = 0; num_strings < MAX_STRINGS ; num_strings++) {
        if( scanf("%29s", s[num_strings]) < 1 ) {
            break;
        }
    }

    for( int i = 0 ; i < num_strings; i++){                                                                               
        printf("i= %d   %s\n",i,s[i]);
    }

    return 0;      
}
Sign up to request clarification or add additional context in comments.

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.