2

I'm fairly new to coding and am currently taking a programming course at school with C. We were given an assignment and I'm having a bit of difficulty with the first part. We're learning how to use the string-handling library (stdlib.h) and the objective of the assignment is to input multiple lines of text from the keyboard. The instructor advised us to use two-dimensional arrays in order to do this, but I'm a bit stuck. Here's the code I've written:

int main(void) {
    char string[3][SIZE];
    int i, j;
    int c;

    printf("Enter three lines of text:\n");

    for (i = 0; i < 3; i++) {
        j = 0;
        while ((j < SIZE) && (c = getchar() != '\n')) {
            string[i][j] = c;
            j++;
        }
    }

    for (i = 0; i < 3; i++) {
        for (j = 0; j < SIZE; j++) {
            printf("%c", string[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Some points that I'd like to make are that I used the getchar() function to receive input one character at a time, and also the second for loop I intended to print each line of text that is stored in each row of the string array.

The input is any string of text for three lines, for example:

Hi my name is John.\n
I am from the US\n
and I'm a student.

Here's what the current output looks like:

Enter three lines of text:
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr...

The output that I'm expecting is:

Enter three lines of text:\n
Hi my name is John.\n
I'm from the US\n
and am a student.

Any tips or advice would be greatly appreciated. Thank you!

5
  • Is it a requirement of the exercise that you work character by character? Commented May 14, 2017 at 3:20
  • 1
    Yes! That's why I used the getchar() function. My instructor recommended since we're studying the string-handling library that we try to utilize as many as we can, regardless of appropriateness or efficiency. Commented May 14, 2017 at 3:53
  • @Sean Thanks for the clarification. BTW string.h is the string handling library. stdio.h is the IO handling library where getchar comes from. stdlib.h is sort of a dumping ground. Commented May 14, 2017 at 4:45
  • fix like this Commented May 14, 2017 at 4:51
  • This c = getchar() != '\n' does not do what you expect. Commented May 14, 2017 at 13:11

2 Answers 2

1

First of all let me commend the fact the you starting your way with C. That's the most solid language to learn(better is only assembly itself) - you will have a full understanding of how things work, which you wouldn't get if started from some language written on top of C(like Java and Python). But it's a hard and long road, which worth that.

On the code: there is a lot going and you have made a lot of amusing bugs that would reproduce different interesting things every other time and machine you run it.

First of all: to make your code work somehow all you need is add parenthesis:

    while ((j < SIZE) && ((c = getchar()) != '\n')) {

In C everything is binary(or integer, depending how you look at it) and default binding is to the right a op1 b op2 c op3 d.. First op3 is evaluated c op3 d = r1, then you have a op1 b op2 r1 and so on. Thus you was comparing the value of getchar() with value of character '\n' - which are not equal, so you get TRUE (value 1) and store it in local variable c.

Next you still have some problems because of the way you initialized your array:

     char string[3][SIZE];

What it does is simply "intrusts" 3*SIZE*sizeof(char) bytes of you process address space to a thing labeled "string". But that does not clear up all the remnants of previous live (of your program, or even before) on those bytes, so if it happens that SIZE in your program == 100 and you used to store your credit card on a real address memory (RAM) mapped to that region of your program memory you would see your credit card when you print it by printf - if you didn't overwrite those 300 bytes.

This may help you looking at it:

#include <stdlib.h>
#include <stdio.h>

#define SIZE 10

int main(void) {
    char string[3][SIZE];
    int i, j;
    int c;

    for(i = 0; i < 3; i++)
      for(j = 0; j < SIZE; j++){
        string[i][j] = 0;
      }
    printf("Enter three lines of text:\n");

    for (i = 0; i < 3; i++) {
        j = 0;
        while ((j < SIZE) && ((c = getchar()) != '\n')) {
            string[i][j] = c;
            j++;
        }
    }

    for (i = 0; i < 3; i++) {
        for (j = 0; j < SIZE; j++) {
            printf("%c", string[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Also be aware that getchar() may behave lousy with input and newlines - it depends on whether you console buffers input before sending it to your program on enter(newline) or not. More here How to avoid press enter with any getchar()

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

Comments

1

Note: I wrote this answer before the OP clarified they had to use getchar.

To read a whole line at a time, use fgets. To print a whole string at a time, use printf with the %s format.

#include <stdio.h>

int main(void) {
    // No need to define a SIZE constant.
    // Because it's stack allocated we can its size.
    char strings[3][100];

    printf("Enter three lines of text:\n");

    for ( int i = 0; i < 3; i++) {
        // Reads one line, up to the size of `strings[i]`, from stdin.
        fgets( strings[i], sizeof(strings[i]), stdin );
    }

    for ( int i = 0; i < 3; i++) {
        // Print each string and its line number.
        printf("Line %d: %s\n", i, strings[i]);
    }

    return 0;
}

This is not the best pattern to read input. You'll learn very quickly that fixed memory sizes and reading input don't work well. For future reference, it would be more like this.

#include <stdio.h>
#include <string.h>

int main(void) {
    // A list to store 3 strings, but no memory for the strings themselves.
    char *strings[3];

    printf("Enter three lines of text:\n");

    // A line buffer that's sufficiently large.
    // This will be reused.
    char line[4096];
    for ( int i = 0; i < 3; i++) {
        // Read into the large line buffer.
        fgets( line, sizeof(line), stdin );

        // Copy the string into a buffer that's just big enough.
        strings[i] = strdup( line );
    }

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

    return 0;
}

This allocates a single large line buffer to do the reading, then copies what its read with strdup to memory of just the right size. This lets you read even very long lines of input without wasting a bunch of memory if they're very short.

Note that strdup() is not part of the C standard library, but it's part of the POSIX spec. Any major compiler will have it, and it's easy to write your own.

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.