1

Forgive me, I'm a C programming rookie. What I need to do is take values from standard input and store them in an array which is to be sorted later on down the line.

The method of entry for the user is one number on one line at a time (i.e. enter a number, press enter, enter number, press enter, etc..). When the user is done entering numbers, they press ENTER without providing a number.

My code for accepting the values and storing them is as follows. You'll probably see the issue immediately, but I'm not seeing it.

#include <stdio.h>
#define MAX 100

int main()
{
    int n, i, array[MAX];

    printf("Enter a list of integers\n");

    for(i = 0; i <= MAX; ++i){
        printf("> ");
        if (scanf("%d", &n) == -1)
            break;
        else
            scanf("%d", &n);
            array[i] = n;
    }

    printf("The array is %d", *array);
    return 0;
}

The picture below is how the program should run. I have the sort code already, and it seems to work quite well. Your help is greatly appreciated.

enter image description here

Karthik Kumar
  • 1,375
  • 1
  • 12
  • 29
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
  • 2
    You have a “[goto fail](https://gotofail.com)”-style bug in your code. Only the `scanf` line after the `else` is executed conditionally. The `array[i] = n;` always happens. You should enclose the lines after `else` in `{curly braces}`. – Zev Eisenberg May 29 '14 at 02:53
  • [http://stackoverflow.com/questions/19794268/scanf-reading-enter-key](http://stackoverflow.com/questions/19794268/scanf-reading-enter-key) and [http://stackoverflow.com/questions/14099473/how-to-scanf-only-integer-and-repeat-reading-if-the-user-enter-non-numeric-chara](http://stackoverflow.com/questions/14099473/how-to-scanf-only-integer-and-repeat-reading-if-the-user-enter-non-numeric-chara) for reference – Robin May 29 '14 at 02:53
  • 2
    I would remove the scanf in the else as well, that way you don't skip every other number. – Retired Ninja May 29 '14 at 02:54
  • Oh, does `scanf` process if it's inside an `if` condition? I didn't know that. These are all very useful comments so far. Thank you all. – Rich Scriven May 29 '14 at 03:01
  • Any code inside a condition part of an `if` statement is first executed, and the return value is evaluated (typically, 0 is considered false, other values are considered true). – Zev Eisenberg May 29 '14 at 03:07
  • Can we make the user input terminate at `if(!scanf("%d", &n))`? Will C understand that? Or something along those lines? – Rich Scriven May 29 '14 at 03:17

2 Answers2

2

You have it doing what you want, you just need a few tweaks. First, enter doesn't return -1, to keep it simple you need to enter ctrl+d to stop input. After your final input, just hit ctrl+d. Take a look:

#include <stdio.h>
#define MAX 100

int main()
{
    int n, i, array[MAX];

    printf("Enter a list of integers [ctrl+d] to end\n");

    for(i = 0; i <= MAX; ++i){
        printf("> ");
        if (scanf("%d", &n) == -1)
            break;
        array[i] = n;
    }
    puts ("");

    int z;
    for (z = 0; z < i; z++)
        printf("The array is %d\n", array[z]);

    return 0;
}

output:

Enter a list of integers [ctrl+d] to end
> 1
> 2
> 3
> 4
> 5
>
The array is 1
The array is 2
The array is 3
The array is 4
The array is 5
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • How would you detect the Enter key (i.e. entering an empty line)? I was trying to write an answer for this, but I got stuck on how to detect that. – Zev Eisenberg May 29 '14 at 03:10
  • Thanks for the answer. Couple of questions. 1. What is `puts("")` doing there? 2. Can I make the array print on one line, like `The array is 1, 2, 3, 4, 5`? Also, the `enter` thing is pretty important. Thanks again. – Rich Scriven May 29 '14 at 03:13
  • It get's a little more complicated. You need to look at `kbhit()` which is a general name for an input routine using `struct termios` to put the keyboard in raw-unbufferd mode to allow you to accept each keystroke without a return. You can then test for the enter key being pressed directly (unsigned int 10). – David C. Rankin May 29 '14 at 03:16
  • `puts("")` was just a hack to force a newline without vargs parsing of printf. It was not the relevant part of the response. I didn't attempt to match the output format shown. It appeared the OP was more concerned about getting the array fill working. – David C. Rankin May 29 '14 at 03:18
  • @RichardScriven if you are interested in an example of kbhit, here is an example source called [**keypress2.c**](http://www.3111skyline.com/dl/dev/prg/src/keypress2.c) – David C. Rankin May 29 '14 at 03:24
  • The [`keypress2.c`](http://www.3111skyline.com/dl/dev/prg/src/keypress2.c) URL has gone AWOL and the Wayback Machine (aka Internet Archive) doesn't have a copy either. – Jonathan Leffler Feb 22 '23 at 17:49
  • The essence of the code is captured in the SO answer to [Hide password input on terminal](https://stackoverflow.com/a/32421674/3422102) – David C. Rankin Feb 23 '23 at 05:02
1

Here is the updated previous answer to exit on enter.

#include <stdio.h>
#define MAX 100

int main()
{
    int n, i, array[MAX];
    char num[MAX];
    int res;

    printf("Enter a list of integers [ctrl+d] to end\n");

    for(i = 0; i <= MAX; ++i){
        printf("> ");
        fgets(num, sizeof(num), stdin);
        res = sscanf(num, "%d", &n);
        if(res != 1)
            break;
        n = atoi(num);
        array[i] = n;
    }
    puts ("");

    int z;
    for (z = 0; z < i; z++)
        printf("The array is %d\n", array[z]);

    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user207064
  • 665
  • 5
  • 14
  • Note that the code should check the return value from `fgets()` because `fgets()` won't overwrite the array if it reads EOF, and that loop could run for a long time (until the program crashes — which it probably will do) unless you type a non-number to terminate the input. – Jonathan Leffler Feb 22 '23 at 17:46