Search code examples
arrayscloopswhile-loop

How to make this while loop finish on new line


#include <stdio.h>

int main() {
    int lista[9999];
    int a;
    int i = 0;

    while (scanf(" %d", &a) == 1)
    {
        lista[i] = a;
        i++;
    }
    return 0;
}

I am expecting an input of integers and spaces in between them, I do NOT want to read this with one scanf because there will be some calculations done depending on the integer. How to make this loop finish on a new line? if (a == "\n") doesn't seem to work.


Solution

  • You cannot change the behavior of scanf() for %d on newline characters. There are alternatives:

    • you can read the whole input line with fgets() (or getline() on POSIX systems) and parse the numbers on the line with strtol() or sscanf().

    • you can read one integer at a time as a string with scanf("%[-+0-9]", buf) and convert them with atoi(), strtol() or sscanf().

    • you can read one character at a time with getchar() and convert the numbers on the fly, stopping at the newline character.

    Here is an example using scanf() and strtol() with format validation:

    #include <errno.h>
    #include <limits.h>
    #include <stdio.h>
    
    int main(void) {
        int lista[9999];
        char buf[20];
        int i = 0;
        while (i < 9999) {
            scanf("%*[ ]");  // skip spaces if any
            if (scanf("%19[-+0-9]", buf) != 1)
                break;
            errno = 0;
            char *p;
            long n = strtol(buf, &p, 10);
            if (p == buf || errno != 0 || *p != '\0'
            ||  n < INT_MIN || n > INT_MAX) {
                printf("invalid number: %s\n", buf);
                continue;
            }
            int a = (int)n;
            lista[i] = a;
            i++;
        }
        if (scanf("%1[\n]", buf) != 1) {
            // no trailing newline
            printf("invalid input\n");
        }
        return 0;
    }
    

    Here is an alternative using just getchar():

    #include <stdio.h>
    
    int main(void) {
        int lista[9999];
        int i = 0;
        int c = getchar();
        while (i < 9999) {
            while (c == ' ')
                c = getchar();
            int sign = c;
            if (c == '+' || c == '-')
                c = getchar();
            if (!isdigit(c))
                break;
            unsigned value = c - '0';
            while (isdigit(c = getchar()))
                value = value * 10 + (c - '0'); 
            a = (sign == '-') ? -value : value;
            lista[i] = a;
            i++;
        }
        if (c != '\n' && c != EOF) {
            // extra input on the line
            printf("invalid input\n");
        }
        return 0;
    }