Inputting Multiple values through Scanf - C - c

I am trying to solve an SPOJ problem. I am stuck here.
For the input, it asks me the following to take as input
Next line contain n elements, ai (1<=i<= n) separated by spaces.
I can use a loop and input each element given separately by the user through scanf. But as per the problem criteria, I am assuming that we need to take the input through scanf at once in a single line. Like scanf("%d %d %d", &a1 &a2 e.t.c).
But the range is like over 10^6, I am not sure how we can dynamically input multiple values through scanf in a single line.

You can run your iteration as you say, because scanf does not care what kind of whitespace separates integer inputs.
So: for (i = 0; i < n; ++i) scanf("%d", &array[i]); will work for inputs of the type:
3 2 1 2 3 8
as well as the type
3
2
1
2
3
8

Does not matter whether you input the numbers in a single line, this will work as scanf ignores the white spaces
int arr[1000001]; // Take an array to store the inputs
for(i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
}

Related

c language error when using comma as separator for multiple number inputs

I have this program where it lets the user input a list of numbers, then the program finds the largest number amongst the inputs, and count how many times that largest number was inputted.
When I use space as a separator, the program runs well. But when I use a comma as a separator, there seems to be a logical error.
Here is my source code:
int i, numberOfIntegers, listOfIntegers, largest = 0, occurrence = 0;
printf("\n \t \t \t Finding the LARGEST integer \n");
printf("\n How many integers do you want to enter? ");
scanf("%i", &numberOfIntegers);
printf("\n Input %i list of integers: \n ", numberOfIntegers);
for (i = 1; i <= numberOfIntegers; i++)
{
printf("\t");
scanf("%i", &listOfIntegers);
if (listOfIntegers > largest)
{
largest = listOfIntegers;
occurrence = 1;
}
else if (listOfIntegers == largest)
{
occurrence++;
}
}
printf("\n The largest value is %i and the number of occurrence is %i \n ", largest, occurrence);
return 0;
Here is an example of output where I use a comma as a separator:
How many integers do you want to enter? 4
Input 4 list of integers:
5, 6, 6, 6
The largest value is 5 and the number of occurrence is 4
Whereas, the correct output should be:
How many integers do you want to enter? 4
Input 4 list of integers:
5, 6, 6, 6
The largest value is 6 and the number of occurrence is 3
Can someone point out where exactly am I doing it wrong?
The basic problem is that when reading input in C, you need to account for every character (potentially) in the input -- every space and every newline and every comma or other punctuation character, as well as all the values you actually care about and want to read.
When using scanf to read input, whitespace is special as it is easy to ignore. Every % directive in the scanf string except for %c, %[ and %% will ignore leading whitespace automatically. With "%i" like you are using, the newline after the 4 in your input is automatically ignored (skipped) by the first scanf call in the loop, and the spaces between the numbers will skipped by later calls. However, any commas (or other punctuation characters) will not be. You need to skip (read) them explicitly. As it is, when your program gets to the scanf call in the second iteration of the loop, the next character to be read is , (not a digit and not whitespace), so the conversion fails and nothing is stored into listOfIntegers and a 0 is returned (no directives matched). Since you ignore the return value of scanf, you don't notice this and blissfully continue with the same value left over from the first iteration.
One thing you could try is scanf("%i,", &listOfIntegers) in your loop. This will read a single , if it appears immediately after your number. If the character after the number is not a , it will do nothing. While this will work for your example, it wont work for an input like
5 , 6, 6 , 6
due to the extra space before the comma. A more accepting possibility is
scanf("%i%*[ \t,;.]", &listOfIntegers)
which will skip (and ignore) all spaces, tabs, commas, semicolons and periods after the number.
In any case, it would also be a good idea to check the return value of scanf:
if (scanf("%i%*[ \t,;.]", &listOfIntegers) < 1) {
... something is wrong -- the next input is not a number
to catch someone entering a letter or some other non-number input.

c: reading negative numbers with scanf()

I'm trying to read a list of input integers with scanf() separated by spaces into an array, but it breaks every time there's a negative number passed. How do I get it to read negative numbers as well?
for (int i = 0; scanf("%u", &val)==1; i++)
stdin:
1 2 -4 5
It will only put 1 and 2 into the array and then stop reading the rest of the numbers (I think because of the '-'?). How would I fix this?
Use the %d specifier instead of %u, %u expects unsigned values only.

Program To Check If A Number Is Present In An Array

I wrote the below C code to check if a number is present in an array whose elements are input by the user. But weirdly it's skipping the the third printf statement, directly taking the input and printing Enter the number you wish to look for after taking that input. What is causing this? Included input and output box below code.
CODE:
#include <stdio.h>
#include <stdlib.h>
void main() {
int arr[30], size, i, num, flag=0;
printf("Enter size of array. \n");
scanf("%d",&size);
printf("Enter %d array elements one by one. \n",size);
for (i=0; i<size; i++) {
scanf("%d \n",&arr[i]);
}
printf("Enter the number you wish to look for. \n");
scanf("%d",&num);
for(i=0;i<size;i++) {
if (num == arr[i]) {
flag++;
}
}
if (flag>0) {
printf("The number %d is present in the array.",num);
} else {
printf("The number %d is not present in the array.",num);
}
}
INPUT/OUTPUT:
Enter size of array.
5
Enter 5 array elements one by one.
1
2
3
4
5
5
Enter the number you wish to look for.
The number 5 is present in the array.
You can see that Enter the number you wish to look for. should come before 5, but it is not so.
Solved
Simply fixed by removing \n from scanf.
In scanf, a space character already represents any whitespace. So in your "%d \n" the function already processes the new line right after the last digit, but then you force it to wait for another newline.
This causes the program to wait for yet another line. After it's input, the program continues and asks for the number to search, and at that point the input was already entered.
Just use only one space in scanf, it will already work for the newline, ideally before the digit itself so that you don't need one extra line to complete the operation:
scanf(" %d", arr + i);
The space in the input format string "%d \n" tells the input system to
consume... all available consecutive whitespace characters from the input
(described here)
So when you enter your last number 5, the system now tries to consume all whitespace characters. To do that, it waits for additional input, until it's not a whitespace. So, paradoxically or not, to consume spaces, the system has to read a non-space, which is the second 5 you input.
To fix this behavior, you can tell your system to input only a number, without consuming whitespace:
scanf("%d",&arr[i]);
However, this will leave the whitespace in the buffer, which may interfere with later input. To discard the whitespace, you can use various techniques, described e.g. here.
In my opinion, the most correct technique (however, maybe the most cryptic one) is
scanf("%d%*[^\n]%*c",&arr[i]);
%d - read the number
%*[^\n] - read a string, terminated by a newline byte; discard it and don't store it anywhere
%*c - read a byte (which is a newline byte); discard it and don't store it anywhere
BTW in your format string "%d \n", there are two whitespaces: a regular space and an end-of-line. They both tell scanf to consume all whitespaces in input. The effect is exactly the same as with one space "%d " or with one end-of-line "%d\n", so this particular format string may be highly confusing to whoever reads your code (including yourself).

scanf("%d", int) good yesterday, not today. What is going on?

I am getting comfortable with the foundations of C:-
There are two iterations of scanf() in this program. The first is fully functional.
The second appearance does nothing and instead quits the program and returns to the standard command prompt line.
Also, my second for loop only prints the first 4 numbers instead of 5.
Here is the code :
int main() {
int i;
int iNum[4]
int iMenu = 0;
printf("\n\n\tPlease enter five numbers: ");
for (i = 0; i < 4; i++) {
scanf("%d ", &iNum[i]);
}
printf("\n\tThank you. Here are your numbers: \n\t");
for (i = 0; i < 4; i++) {
printf("%d", iNum[i]);
}
printf("\n\tMenu:");
printf("\n1\tSort your numbers ascending.");
printf("\n2\tSort your numbers descending.");
printf("\n3\tQuit program");
printf("\n\nWhat would you like to do?\n\tEnter your option here: ");
scanf(" %d", &iMenu);
switch (iMenu) {
case 1:
printf("\nCase1testPrint");
sortAsc();
break;
case 2:
printf("\nCase2testPrint");
sortDesc();
break;
. . .//rest of code }
As soon as the program reaches the second scanf(), the program ends and returns to command prompt.
This is baffling, and I have tried many variations on what could be wrong. Please provide what you may.
Here is what it looks like if I run the program. Notice my entry "1" appears in the command line instead of the program:
C:\Users\Cortland\Documents\C projects>gcc arraysort.c
C:\Users\Cortland\Documents\C projects>a
Please enter five numbers: 3
6
5
4
5
Thank you. Here are your numbers:
3 6 5 4
Menu:
1 Sort your numbers ascending.
2 Sort your numbers descending.
3 Quit program
What would you like to do?
Enter your option here:
C:\Users\Cortland\Documents\C projects>1
Your for loop reads four numbers, not five.
You enter five numbers. The first four are read in the for loop. The fifth is read by
scanf(" %d", &iMenu);
So you've entered 3 6 5 4 as the four numbers, and then 5 as the choice of what to do. You haven't shown us the entire switch statement, but my guess is that it doesn't handle the value 5, and that it falls through and your program terminates.
(Also, you should always check the value returned by scanf(), and take some action if it indicates that the input operation failed.)
There are a couple of errors.
First off, the second line of your main() function contains a syntax error - there should be a semicolon at the end. This should stop your program from even compiling.
Second, even though you say you want the user to enter 5 numbers, your array and loops all use the number 4. The reason your program still allows you to enter five numbers, however, is because of how you've written the formatting string in your calls to scanf(). Instead of:
scanf("%d ", &iNum[i]);
use
scanf("%d", &iNum[i]);
Notice the lack of a space at the end of the formatting string? That's where your problems come in. Even though you are allowed to enter five numbers, the program only stores and checks four of them. The last number is stuck in the input stream - until, that is, your next call to scanf(). This fetches your last number, which is put through the switch/case statement (failing all cases, since you didn't input "1", "2" or "3"), and the program reaches the end of main() and exits. The "1" in the command line comes from trying to input something when the program has already ended.
Summarized:
1: Add the missing semicolon
2: Change the number used in the declaration of iNum and in the for loops from 4 to 5
3: Edit your scanf() calls, removing whitespace from the formatting strings.
This fixed the problem on my end.

How to take 2 inputs in a single line in C language?

for(i=0;i<t;++i)
{
scanf("%d",&arr[i]);
scanf("%d",&brr[i]);
a=arr[i];
b=brr[i];
}
This code block is taking inputs in two separate line(after pressing enter),ex
12
45
How to modify it so that it take both the numbers in a single line(after pressing space),ex
12 45
How to modify it so that it take both the numbers in a single
line(after pressing space)
Your code already does this (it already works if you pass "12 45" - you can put any amount of whitespace between them). If you want to you can use a single scanf call with something like:
scanf("%d %d", &arr[i], &brr[i]);
When using scanf it is a wise decision to check the return code, i.e. the number of scanned elements.
rc = scanf(...);
if (rc != 2)
/* We scanned less than we expected! */

Resources