Looping scanf horizontally - c

If I use this code:
int a, b[100];
scanf("%d", &a);
for (int x = 0; x < a; x++) {
scanf(" %d", &b[x]);
}
For example if
1st input: 3
2nd input: 4
3rd input: 3
4th input: 1
The output on the screen will be like this (because I use enter at the end of the scanf on every loop)
3
4
3
1
I want to make a code which will loop the second scanf in the for loop horizontally without pressing enter (but use space) until the end of the loop, like this:
scanf(" %d %d %d", &b[x], &b[x+1], &b[x+2]);

You can type the count and the entries on a single line, separated by spaces and the current code will parse them in a single uninterrupted flow because scanf() skips any whitespace before a value for %d, be it spaces, tabs, newlines...
Note that the format " %d" is redundant: %d skips any pending whitespace before the integer, and a space in the format string means exactly the same thing. Just use scanf("%d", &b[x]);
Note also that you should add a safety check to avoid scanning values beyond the end of the array and you should test the return value of scanf() to avoid undefined behavior on invalid input.
Here is a modified version:
#include <stdio.h>
int main() {
int a, x, b[100];
if (scanf("%d", &a) == 1) {
for (x = 0; x < 100 && x < a; x++) {
if (scanf("%d", &b[x]) != 1)
break;
}
printf("read %d values:", x);
for (int i = 0; i < x; i++)
printf(" %d", b[i]);
printf("\n");
}
return 0;
}

The scanf function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).
So whether you use ENTER (newline) or a SPACE (single or multiple) does not make a difference for reading the input values in this case.
See this online reference for scanf for more details on how scanf works.

Related

Printing an extra underscore, I'm not sure why, only happens once before clearing the screen [duplicate]

This question already has answers here:
scanf getchar function is skipped
(3 answers)
Closed 6 years ago.
I am trying to make a simple C program for a class and one of the requirements is that I'm required to use scanf/printf for all input and output. My question is why is it that my scanf after the for loop in the main gets skipped and the program just terminates.
Here is my code
#include <stdio.h>
void main() {
int userValue;
int x;
char c;
printf("Enter a number : ");
scanf("%d", &userValue);
printf("The odd prime values are:\n");
for (x = 3; x <= userValue; x = x + 2) {
int a;
a = isPrime(x);
if (a = 1) {
printf("%d is an odd prime\n", x);
}
}
printf("hit anything to terminate...");
scanf("%c", &c);
}
int isPrime(int number) {
int i;
for (i = 2; i < number; i++) {
if (number % i == 0 && i != number)
return 0;
}
return 1;
}
I was able to "fix" it by adding another identical scanf after the first one, but I would prefer to just use the one.
The new-line character present in stdin after the previous int was entered will not have been consumed by the last call to scanf(). So the call to scanf() after the for loop consumes the new-line character and continues without the user having to enter anything.
To correct without having to add another scanf() call you could use format specifier " %c" in the scanf() after the for loop. This will make scanf() skip any leading whitespace characters (including new-line). Note it means the user will have to enter something other than a new-line to end the program.
Additionally:
check the result of scanf() to ensure it actually assigns a value to the variables passed in:
/* scanf() returns number of assigments made. */
if (scanf("%d", &userValue) == 1)
this is an assignment (and will always be true):
if (a = 1){ /* Use == for equality check.
Note 'a' could be removed entirely and
replace with: if (isPrime(x)) */

Why is scanf(); skipping the first line?

So after scanf, the printf(); skips the first line
I have read some questions that tells that , "%[^\n]" must be " %[^\n]" to skip the newline.
I have tried it both, but it still print the same result and now I don't know why it doesn't work.
Example input
Enter number of Materi: 4
Materia 1 name : a
Materia 2 name : b
materia 3 name : c
materia 4 name : d
Output:
Materia - 1 : R╒fu
Materia - 2 : a
Materia - 3 : b
Materia - 4 : c
#include<stdio.h>
#include<windows.h>
int main(int argc, const char *argv[]){
int i;
int V;
printf("Enter number of Materi: ");
scanf("%d", &V); fflush(stdin);
//Insert materia
char materia[V][50];
for(i = 0; i < V; i++){
printf("Materia %d name : ", i+1);scanf("%[^\n]", &materia[i][50]);fflush(stdin);
}
for(i = 0; i < V; i++){
printf("Materia - %d: %s\n", i+1, materia[i]);
}
system("pause");
return 0;
}
There are several mistakes in the program
The array passed to scanf is wrong.
fflush(stdin) is non-standard, although Windows does support it it's not portable. But you aren't using Windows because it does not support the VLA char materia[V][50];
The newlines which the scanf format "%[^\n]" will stop at, are already the next character in the input buffer.
The return value from scanf was not checked. It is the number of items successfully scanned.
You can have buffer overflow because the input string length is not restricted.
Here is the adjusted code:
#include<stdio.h>
int main(int argc, const char *argv[]){
int i;
int V;
printf("Enter number of Materi: ");
if(scanf("%d", &V) != 1) {
/* add some error message */
return 1;
}
// fflush(stdin); // removed
//Insert materia
char materia[V][50];
for(i = 0; i < V; i++){
printf("Materia %d name : ", i+1);
// add a space to filter the newline
// correct the array passed
// and restrict the length to prevent buffer overflow
if(scanf(" %49[^\n]", materia[i]) != 1) {
/* add some error message */
return 1;
}
// fflush(stdin); // removed
}
for(i = 0; i < V; i++){
printf("Materia - %d: %s\n", i+1, materia[i]);
}
return 0;
}
About the newlines. Format specs %d and %s and %f automatically filter out leading whitespace, but %c and %[] and %n do not. The scanf functions stop at the first character they cannot convert, which is left in the input buffer. The %[^\n] tell it to stop at the first newline. But there is one already there, from the first %d scanf and it needs to be removed, also in subsequent iterations and adding the space does that job. Trying to remove it afterward is clumsy and not guranteed to work.
You must check the return value from scanf every time it is used. It is the number of items successfully scanned. Here, it should be 1 in both uses. So if you have two items in one statement, its return value must be 2.
In the line:
scanf("%[^\n]", &materia[i][50]);
You are storing the inputed string in the address of materia[i][50], effectively storing it outside the bounds of the array.
Something interesting happens here, 2D array storage is contiguous as if it was a one dimensional vector, what happens is you are storing the first string in the beginning of the second line of the array, the second on the third and so on, leaving the first empty. That's the rational for the output the program produces.
Correct you code with:
#include<stdlib.h>
//...
if(scanf(" %49[^\n]", materia[i] != 1) {
puts("Read error");
return EXIT_FAILURE;
}
49 character + the nul terminator to avoid overflow, a space in the beginning of the specifier avoids the consuption of blank characters left in the stdin buffer. Always verify scanf return to avoid reading errors.
Some other issues:
fflush(stdin) should be removed as fflush is meant to be called on an output stream.
Variable lenght arrays can cause stack overflow if enough memory is consumed, in this case it's not likely, but it's something to keep in mind.
Use fgets instead of scanf. The newline character is consumed as a character by your subsequent scanf. That's why you are facing this problem.

Why this program is generating wrong answer?

This program is not giving the correct output; and it is taking input once instead of 't' times, while entering for the first time in the for-loop.
This problem is HEADBOB (https://www.codechef.com/problems/HEADBOB)
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
for(t; t>0; t--)
{
int J=0, Y=0, N=0, I=0, len=0;
if(len==0)
scanf("%d", &len);
char ar[len];
for(J=0; J<len; J++)
{
scanf("%c",&ar[J]);
if(ar[J]=='Y')
Y++;
else if(ar[J]=='N')
N++;
else if(ar[J]=='I')
I++;
}
if(I>0)
printf("INDIAN\n");
else
{
if((Y&&!N)||(N&&!Y))
printf("NOT SURE\n");
else if(Y&&N) printf("NOT INDIAN\n");
}
}
}
INPUT:
NUMBER OF TEST CASES
NUMBER OF CHARACTERS
N NUMBER OF CHARACTERS
SAMPLE INPUT & OUTPUT OF ABOVE CODE:
INPUT:
5
5
NNYNN
OUTPUT:
NOT INDIAN
Check, if scanf("%c", &ar[j]) is reading whitespace characters! Think about
scanf(" %c", &ar[j]);
That means to skip all whitespace characters (space, tabs, \ns, etc).
Or even better:
scanf("%d", &len);
char ar[len + 1]; // + 1 for 0-termination
scanf(" %s", ar); // skip all whitespace characters, then read a string
Reading full string in one shot is a lot faster.
The problem is that the second scanf (scanf("%d", &len);) leaves a newline character in the standard input stream (stdin). This character is then consumed by the third scanf (scanf("%c",&ar[J]);) in the first iteration of the loop.
Changing
scanf("%d", &len);
to
scanf("%d%*c", &len);
will fix the problem. %*c tells scanf to read and discard a character.

Scanf does not read user input as expected

The program is not taking inputs as it should. When I input t = 1 and l = 4 the inner loop takes only two inputs instead of four.
int main() {
int l, b, g, count, t, i;
char s[10000];
scanf("%d%d", &t, &l);
while (t--) {
for (i = 0; i < l; i++) {
scanf("%c", s[i]);
if (i > 0)
if (s[i] == s[i-1])
count++;
}
printf("%d\n", count);
}
getch();
}
The problem is that when you enter a character for any scanf, you press the enter key. The input(if valid) is consumed by the scanf and the newline character(since you pressed the enter key) stays in the standard input stream(stdin). When scanf(with %c) is called the next time, it sees the \n character in the stdin and consumes it, and thus does not wait for further input.
To fix it, Change
scanf("%c",s[i]);
To
scanf(" %c",&s[i]);
The space before the %c instructs scanf to scan any number of whitespace characters including none, until the first non-whitespace character. Quoting the standard:
7.21.6.2 The fscanf function
[...]
A directive composed of white-space character(s) is executed by reading input up to the
first non-white-space character (which remains unread), or until no more characters can
be read. The directive never fails.
scanf with the %c format specifier expects a char* or in other words, the address of a char. You provide the argument s[i] which is of type char. This invokes Undefined behavior. & is the address of operator, and it, when used before s[i], gives the address of s[i], which is a char*.
int main(){
int l,b,g,count,t,i;
char s[10000];
scanf("%d%d",&t,&l);
getchar();
while(t--){
for(i=0;i<l;i++){
scanf("%c",s[i]);
if(i>0)
if(s[i]==s[i-1])
count++;
}
printf("%d\n",count);
}
getch();
}
The two getchars are used to clear the '\n' that is there in the input buffer. The dummy getchars are just taking those extra '\n' and that will solve the problem.

Scan single character C

/*
Program to calculate trip and plan flights
*/
#define TRIP 6
#define DEST 1
#include <stdio.h>
int error_dest(int type_num, int cont_num, int dest_code, int check);
int main(void)
{
int check, type_num, cont_num, index, i, dest_code, trip_num, row, col;
int travelint[TRIP][DEST], travelarea[TRIP];
char area_code, S, M, L, N, P, K, R, C, U, W, O;
trip_num = 7;
while (trip_num > TRIP)
{
printf("Please enter the number of trips:");
scanf("%d", &trip_num);
if ( trip_num < TRIP)
{
printf("Valid trip number. Please proceed to enter destination code.\n");
}
else
{
printf("Invalid trips. Please enter no more then 6 trips.\n");
}
}
/*********************************************************************************/
for (i=0; i < trip_num ; i++) /*destination code input*/
{
printf("Please enter destination code:");
scanf("%d", &dest_code); /*input of destination code*/
check = error_dest(type_num, cont_num, dest_code, check);
if (check == 2)
{ travelint[i][0]=dest_code; }
else
{
while (check == 1)
{
printf("Please enter destination code:");
scanf("%d", &dest_code); /*input of destination code*/
check = error_dest(type_num, cont_num, dest_code, check);
if (check == 2)
{ travelint[i][0]=dest_code; }
}
}
printf("Please select from the following that best describes your destination:\n");
printf("S Small city - population under 50,000\n");
printf("M Medium city - population between 50,000 and 500,000\n");
printf("L Large city - pop. over 500,000\n");
printf("N Natural formation like a mountain, a lake, a cave, a geyser, a fjord, a canyon, etc.\n");
printf("P Designated park or reserve such as a wildlife refuge, a national park, a bioreserve, or a protected marine area\n");
printf("K Man made landmark like the Great Wall of China, the Taj Mahal, or Stonehenge\n");
printf("R State or province or region of a country\n");
printf("C Whole country\n");
printf("U Multiple countries like traveling through Europe\n");
printf("W Ocean voyage\n");
printf("O Any other type of destination - such as visiting the sites of the seven wonders of the world\n");
printf("Please enter the Area Letter code:");
scanf("%c", &area_code);
}
/*******************************************************************************/
/*print for destination_code*/
for (row = 0; row < trip_num; row++)
{
for (col=0; col < DEST; col++)
printf("Trip[%d] = %d\n", row+1, travelint[row][col]);
}
return 0;
}
error_dest(type_num, cont_num, dest_code, check)
{
cont_num = dest_code / 10000; /*math for error check*/
type_num = dest_code/1000 - cont_num*10;
if ( (cont_num <= 7) && (cont_num > 0) && (type_num <= 5) && (type_num >=0) )
{ /* loop for checking destination code*/
check = 2 ;
return check;
}
else
{
printf("%d is a invalid code\n", dest_code);
check = 1;
return check;
}
}
for some strange reason at the scanf("%c", &area_code); it just runs ahead and print the dest_code array without letting me input any character and I'm not sure what exactly I am doing wrong.
If you're looking to grab only one character, perhaps it would be better to use getchar() instead of scanf()?
Basically what's happening is this: you print the "Please enter the number of trips" message to the screen. The user types in 4 and then hits the enter key, which means the stdin buffer looks like this: "4\n". You then call scanf with the "%d" format string. scanf looks at the stdin buffer, and sees the 4. It looks at the next character, which is the newline, and sees it's not part of a number (as %d specifies), so it is done fulfilling the format string and leaves the file pointer at the newline. It converts the char '4' to an integer 4 and places it in trip_num and returns.
The next time you call scanf, it picks up where it left off at the newline. The format string this time is "%c", so it just grabs the next character from the buffer which is currently the newline ("\n"), places it in dest_code, and returns. If you want the scanf function to skip over the whitespace in this case, you have to explicitly tell it by adding a space before the "%c" format for the second scanf (destination code). Then scanf will skip over all whitespace (including that newline) until it encounters a non-whitespace character that it places in dest_code.
TL;DR: Change the second scanf call to scanf(" %c", &dest_code). And fix the other errors others have pointed out so other bugs won't manifest.
You may print area_code after scanf, I guess it may be '\n' which is the last character of the dest_code line you entered.
You should empty the buffer before reading a character from stdin:
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
then you can read your character using scanf or replace it with getchar.
This may or may not help, but previously stated you probably need to put the getchar() into the while loop. You may also need the fgets to grab the stdin from the keyboard.
while(1){
printf("Enter Message Type:");
fflush(stdout) ;
// scan msg.hdr from received message.
scanf("%d", &(msg.m_hdr));
while(getchar() != '\n'){}
printf("Enter your Message:");
fflush(stdout);
// grab data from keyboard
fgets(msg.m_data, sizeof(msg.m_data), stdin);
Use "fflush(stdin)" before you enter the character, i.e. before the "printf" statement for the character. It will flush out the input buffer and thus you can scan the desired character. Or simply give a Space before the "%c" command. Like---------- scanf(" %c", &area_code); ---------------

Resources