5

I am trying to read an unknown number of inputs using scanf function.

int a[100];
int i = 0;

while((scanf("%d", &a[i])) != '\n')
 i++;

// Next part of the code

But this function is not going to next part of the code, seems like there is an infinite while loop.

How Do I solve this logical error? Is there any other alternatives to scanf like sscanf to read integers into an array?

Antonio
  • 19,451
  • 13
  • 99
  • 197
user2147954
  • 2,045
  • 3
  • 15
  • 10
  • How do you want to mark the end of input? – Avidan Borisov Mar 08 '13 at 10:15
  • Suppose the user starts entering a list of numbers say 10 space 20 space 30 and after they have finished entering they should press enter key to come out of the loop – user2147954 Mar 08 '13 at 10:17
  • Return Value of scanf is the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure. So the comparison with `\\n` is not correct. – uba Mar 08 '13 at 10:17
  • Because that is `getchar` which returns the next character from stdin, not `scanf` – uba Mar 08 '13 at 10:23
  • `n = scanf("%d%d ... %d", a+0, a+1, ..., a+99); printf("%d numbers\n", n);` – pmg Mar 08 '13 at 10:33

6 Answers6

8

scanf returns the number of input items that have been successfully matched and assigned, thus it is reasonable to do:

while(scanf(...) == 1)

Now you want to be able to read multiple numbers, each defined on the new line. Then you could simply do this:

int array[100];
int i = 0;

while(i < 100 && scanf("%d\n", &array[i]) == 1)
    i++;

note that this reading will stop only if invalid input is entered (for example letter q) or when you input the end-of-input control code, which is Ctrl+Z (on Windows) or Ctrl+D (on Mac, Linux, Unix).

LihO
  • 41,190
  • 11
  • 99
  • 167
  • 1
    Note that the trailing `\n` in the `scanf()` format string is a user-interface disaster if users will type the input. The input for the first number doesn't end until you type something (presumably the second number) that is not white space. Further, the newline in the format string matches any white space — blanks or tabs as well as new lines; it emphatically does not demand a newline. And, final nail in the coffin for the time being, the numeric conversion specifications like `%d` skip over (leading) white space automatically. Only `%c`, `%[…]` (scan sets) and `%n` do not skip spaces. – Jonathan Leffler May 03 '17 at 14:57
  • 1
    Recommendation: remove the `\n` from the format string. The code will work better when a human is typing. (It won't be obvious to the user that there's a problem as there's no feedback between numbers being entered. So you get away with in this example. In other contexts, there would be problems requiring the user to be prescient — knowing what to enter next.) – Jonathan Leffler May 03 '17 at 15:00
  • 1
    See [What is the effect of a trailing blank in a scanf() format string?](http://stackoverflow.com/questions/19499060/) – Jonathan Leffler May 03 '17 at 15:03
2

The return value of scanf is the number of input items successfully matched and assigned, so try this to end when a non-numeric input is encountered:

while (i < 100 && (scanf("%d", &a[i])) == 1) { i++; }
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • @user2147954: Because the reading continues until invalid input or EOF is entered. See my answer. – LihO Mar 08 '13 at 10:38
0

You want to do

char discard;

while(i < 100 && (scanf("%d%1[^\n]s", &arr[i], &discard)) == 2)
 i++;

to keep getting input till a new line.

scanf() isn't the best tool for reading entire lines. You should use fgets() to read the line and then parse it using sscanf() or other functions.

Avidan Borisov
  • 3,235
  • 4
  • 24
  • 27
0

The return value of scanf is the number of scanned inputs per call. You can compare it to integer 10 (or '\n'), which would stop the loop when the scanf actually read 10 items. (And to do that, it would have to have ten specifiers in the format string.

You can try

   while((i<10) && (scanf("%d",a+i)==1)) i++;

Accepting any number of arguments has to be programmed eg. as

   while (fgets(mybuf, ALLOCATED_LENGTH-1, stdin)) {
        char *p = mybuf;
        if (*p=='\n') break; // or a better function to test for empty line
        while (custom_scan_next_integer(&p)) i++;
   }

where custom_scan_next_integer modifies the pointer p to forward the proper amount of characters.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • This works, but missing the whole point of reading unkown number of inputs into an array. magic number 10 is not good. The point is I dont know how many numbers the user will enter before pressing enter key – user2147954 Mar 08 '13 at 10:29
0

First replace "%d" by " %d" this will avoid the new line problems

second if your input contain non numeric input then your while loop will enter in the infinite loop. so you have to check your input if it's a numeric input

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
0

i think the main problem is you do not know how many number you should read from input i found this answer from somewhere else and this is not mine , but is a great trick

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

int main() { 
    int i=0, j=0; 
    int arr[10000]; 
    char temp; 
    do { 
       scanf("%d%c", &arr[i], &temp); 
       i++; 
    } while(temp != '\n'); 

    for(j=0; j<i; j++) { 
       printf("%d ", arr[j]); 
    } 

    return 0; 
}

this code belongs to Abhishek Bhattacharya (from Quora) (first answer)

AHTI
  • 1
  • 2