Exit out of a loop after hitting enter in c - c

How should i exit out of a loop just by hitting the enter key:
I tried the following code but it is not working!
int main()
{
int n,i,j,no,arr[10];
char c;
scanf("%d",&n);
for(i=0;i<n;i++)
{
j=0;
while(c!='\n')
{
scanf("%d",&arr[j]);
c=getchar();
j++;
}
scanf("%d",&no);
}
return 0;
}
I have to take input as follows:
3//No of inputs
3 4 5//input 1
6
4 3//input 2
5
8//input 3
9

Your best bet is to use fgets for line based input and detect if the only thing in the line was the newline character.
If not, you can then sscanf the line you've entered to get an integer, rather than directly scanfing standard input.
A robust line input function can be found in this answer, then you just need to modify your scanf to use sscanf.
If you don't want to use that full featured input function, you can use a simpler method such as:
#include <stdio.h>
#include <string.h>
int main(void) {
char inputStr[1024];
int intVal;
// Loop forever.
for (;;) {
// Get a string from the user, break on error.
printf ("Enter your string: ");
if (fgets (inputStr, sizeof (inputStr), stdin) == NULL)
break;
// Break if nothing entered.
if (strcmp (inputStr, "\n") == 0)
break;
// Get and print integer.
if (sscanf (inputStr, "%d", &intVal) != 1)
printf ("scanf failure\n");
else
printf ("You entered %d\n", intVal);
}
return 0;
}

There is a difference between new line feed (\n or 10 decimal Ascii) and carriage return (\r or 13 decimal Ascii).
In your code you should try:
switch(c)
{
case 10:
scanf("%d",&no);
/*c=something if you need to enter the loop again after reading no*/
break;
case 13:
scanf("%d",&no);
/*c=something if you need to enter the loop again after reading no*/
break;
default:
scanf("%d",&arr[j]);
c=getchar();
j++;
break;
}
You also should note that your variable c was not initialized in the first test, if you don't expected any input beginning with '\n' or '\r', it would be good to attribute some value to it before the first test.

change
j=0;
to
j=0;c=' ';//initialize c, clear '\n'

When the program comes out of while loop, c contains '\n' so next time the program cannot go inside the while loop. You should assign some value to c other than '\n' along with j=0 inside for loop.

Related

Issue while creating a simple calculator in C

I am creating a very basic calculator in C but the output is not coming as desired.
#include<stdio.h>
int main(int argc, char const *argv[])
{
/* code */
char ch;
int a,b,p=0;
scanf("%d",&a);
while(1)
{
ch=getchar();
if(ch==';')
{
p=2;
break;
}
scanf("%d",&b);
if(ch=='+')
{
a+=b;
}
if(ch=='-')
{
a-=b;
}
if(ch=='*')
{
a*=b;
}
if(ch=='/' && b!=0)
{
a/=b;
}
if(ch=='/' && b==0)
{
printf("INVALID INPUT\n");
p=2;
break;
}
}
if(p!=0)
printf("%d",a);
return 0;
}
The Output is always coming as the initial value which has been assigned to "a".
Output which is coming-
4
+
5
;
4
Expected output -
4
+
5
;
9
Can you please help me with this issue of why the expression is not getting evaluated correctly?
The line
scanf("%d",&a);
will consume the first number from the input stream, but it will leave the newline character on the input stream.
Therefore, when you later call
ch=getchar();
it will read that newline character. It will not read the + character.
If you want to read the + character, then you can change that line to the following:
scanf( " %c", &ch );
This line will first discard all whitespace characters and will match the first non-whitespace character on the input stream.
Afterwards, your program will have the desired output:
4
+
5
;
9
An alternative solution would be to discard the rest of the line after every call to scanf that uses the %d format specifier. That way, calling getchar immediately afterwards should read the + character as intended.
You can discard the remainder of an input line using the following code:
//discard remainder of input line
{
int c;
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
}
Here is a more compact way of writing the same thing:
//discard remainder of input line
for ( int c; (c=getchar()) != EOF && c != '\n'; )
;
The only problem is in scanning the inputs.
As a tab or a new line must seperate the value supplied to scanf.
In short, just add \n at the end of scanf.
scanf("%d\n", &a);
scanf("%d\n", &b);
this should do it.

Scanning character caused problem in devC

So my code does the following:
Ask what's the option
If option is 1: Scan some numbers
If option is 2: Print those numbers
After each option, ask if user wanted to continue choosing (Y/N)
This is my main code
while(yesnocheck==1)
{
printf("What's your option?: ");
scanf("%d",&b);
switch(b){
case 1:
printf("How many numbers?: ");
scanf(" %d",&n);
a=(struct sv*)malloc(n*sizeof(struct sv));
for(int i=0;i<n;i++)
scanf("%d",&((a+i)->num));
break;
case 2:
for(int i=0;i<n;i++)
printf("%d\n",(a+i)->num);
break;
}
yesnocheck==yesnochecker();
}
And this is the yesnochecker function:
int yesnochecker()
{
char yesorno;
printf("Do you want to continue? (Y/N)");
while(scanf("%s",&yesorno))
{
if(yesorno=='Y')
return 1;
if(yesorno='N')
return 0;
printf("*Wrong input. Please reenter (Y/N): ");
}
}
So on dev C++, my code won't run correctly. After it's done option 1, when I enter "Y" then choose option 2, case 2 will display some weird numbers. However it works well on online C compilers.
And then, when I change the char yesorno in yesnochecker() function to char yesorno[2] and treat it as a string, the code does work.
Can someone shed some light?
It is a bad idea to read a char c with scanf("%s", &c);. "%s" requires a buffer to store a string. The only string which fits into a char is an empty string (consisting only of a terminator '\0' – not very useful). Every string with 1 character requires 2 chars of storage – 1 for the character, 1 for the terminator ('\0'). Providing a char for storage is Undefined Behavior.
So, the first hint was to use the proper formatter instead – "%c".
This is better as it removes the Undefined Behavior. However, it doesn't solve another problem as the following sample shows:
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n):
Input '
'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
WTH?
The scanf("%c") consumes one character from input. The other character (inserted for the ENTER key) stays in input buffer until next call of any input function.
Too bad, without ENTER it is hard to confirm input on console.
A possible solution is to read characters until the ENTER key is received (or input fails for any reasons). (And, btw., getc() or fgetc() can be used as well to read a single character.):
#include <stdio.h>
int cont()
{
int c;
do {
int d;
printf("Continue (y/n): ");
if ((c = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
printf("Input '%c'\n", c);
for (d = c; d != '\n';) {
if ((d = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
}
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): Hello↵
Input 'H'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
Please, note, that I changed the type for the read character to int. This is because getc()/fgetc() return an int which is capable to store any of the 256 possible char values as well as -1 which is returned in case of failing.
However, it isn't any problem to compare an int with a character constant (e.g. 'y'). In C, the type of character constants is just int (SO: Type of character constant).

scanf("%d",a) with a "while" grammar bypass the scanf

if there is no initialization ("mod=0") , this code go infinite loop.
I can't understand why this code go loop, even if I used getchar();
to erase the buffer.
when I typed "1" first, and typed "a" next, there goes an infinite loop.
Can anybody help me with understanding this situation?
int main()
{
srand((unsigned)time(NULL));
int mod = 0;
int val = 0;
do {
printf("\t-----------------------------\n");
printf("\t|%5s %5s %5s %5s|\n", "1.create", "2.modify", "3.print", "4.quit");
printf("\t|%15s","Input command : ");
scanf("%d", &mod);
printf("\t-----------------------------\n");
switch (mod){
case 1: random(); val++; break;
case 2: if(val != 0) { modify(); break; }
case 3: if(val != 0) { print(); break; }
default: getchar(); printf("\tUnknown Command!! Retry!! \n"); break;
}
} while (mod != 4);
}
I compiled this code with Visual Studio 2015.
When you input a, it's an invalid input for mod as scanf() expects an int for %d. So it's not read into mod. So the mod is left with the value of mod inputted in the previous iteration.
And the reason it goes in an infinite loop is because scanf() doesn't discard the invalid input. So repeatedly attempts to read a and fails and loop goes on.
Check the return value of scanf() and discard any invalid input(s).
scanf() is notoriously bad for reading user input and proper handling input failures is generally harder using it.
A better approach is to read a line input using fgets() and then parse it using sscanf().
do {
...
printf("\t|%15s","Input command : ");
fgets(line, sizeof line, stdin);
char *p = strchr(line, '\n');
if(p) *p = 0; /* remove tailing newline, if present */
if( sscanf(line, "%d", &mod) != 1) {
printf("Invalid input\n");
continue;
}
printf("\t-----------------------------\n");
....
}while (mod != 4);
The problem with your code is, that once you typed in an number, which is a valid menu option, the variable mod is always equal to the same number, that was input during the first time you entered it, if you enter a wrong input the second time. This behavior comes from the fact, that
scanf(%d, &mod);
tries to read an integer, but as you entered an 'a' as a second option for example, the input is not able to read an integer from your Standard input. So it will not enter the default case of your switch method, as the variable mod is equal to the input from the first valid input you entered.

Program looping two times (printing statement twice)

I'm trying to make a simple program for which the user is supposed to enter character 'a'. It is supposed to loop until 'a' is input. I have one statement printed if there is no input which works correctly. There is another statement if an incorrect letter or number is input, but the problem is that this causes the program to loop more than once and it prints the statements multiple times. Any help in fixing this is appreciated.
#include <stdio.h>
int main()
{
char input;
int i, len,num;
len = 1;
do
{
puts("Please enter alphabet 'a': ");
scanf("%c", &input);
for(i=0; i<len; i++)
{
if(isalpha(input)==0)
{
printf("Please input something.\n");
continue;
}
if(input == 'A' || input == 'a')
{
printf("Congratulations! You successfully input letter 'a'.");
return(0);
}
else
{
printf("That's not letter 'a'.");
}
}
}
while(1);
}
The problem is that after entering the character, you press newline and this is send to the input buffer. Now the next time scanf() is called, it reads the value from the buffer which is '\n' and scanf() thus stores this to input. Now this can be easily solved by the method pointed by #Gopi, but there is a better way. This is the code.
#include <stdio.h>
#include<ctype.h>
int main()
{
char input,ch;
do
{
puts("Please enter alphabet 'a': ");
scanf("%c", &input);
while( input!='\n' && (ch=getchar())!='\n' && ch!= EOF); // look here
if(isalpha(input)==0)
{
printf("Please input something.\n");
continue;
}
if(input == 'A' || input == 'a')
{
printf("Congratulations! You successfully input letter 'a'.");
return(0);
}
else
{
printf("That's not letter 'a'.");
}
}
while(1);
}
Now with the statement while((ch=getchar())!='\n' && ch!= EOF);, all the characters like '\n' are just flushed and not stored to input and thus solves the problem.
Also note that you don't need the for loop here, its useless for this code ( unless this is not your original code and there are other parts in it ).
There is a newline character in the buffer after the first input which is not flushed and that is being picked up by the %c in the second iteration.
Change your scanf() to
scanf(" %c", &input);
Note the space before %c which gobbles the newline character

How to limit input length with scanf

In this program I have taken a dimensional character array of size[3][4],
as long as I enter a 3 characters for each row it will work well.
For example: if I enter abc abd abd I get the same output but if i enter more letters in the first or second or 3rd row I get an error.
How should I check for null character in 2 dimensional?
# include <stdio.h>
#include <conio.h>
# include <ctype.h>
void main()
{
int i=0;
char name[3][4];
printf("\n enter the names \n");
for(i=0;i<3;i++)
{
scanf( "%s",name[i]);
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
getch();
}
As pointed out by #SouravGhosh, you can limit your scanf with "%3s", but the problem is still there if you don't flush stdin on each iteration.
You can do this:
printf("\n enter the names \n");
for(i = 0; i < 3; i++) {
int c;
scanf("%3s", name[i]);
while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
}
How should I chk for null character in 2 dimensional ... [something has eaten the rest part, I guess]
You don't need to, at least not in current context.
The problem is in your approach of allocating memory and putting input into it. Your code has
char name[3][4];
if you enter more that three chars, you'll be overwriting the boundary of allocated memory [considering the space of \0]. You've to limit your scanf() using
scanf("%3s",name[i]);
Note:
change void main() to int main(). add a return 0 at the end.
always check the return value of scanf() to ensure proper input.
EDIT:
As for the logical part, you need to eat up the remainings of the input words to start scanning from the beginning of the next word.
Check the below code [Under Linux, so removed conio.h and getch()]
# include <stdio.h>
# include <ctype.h>
int main()
{
int i=0; char name[3][4];
int c = 0;
printf("\n enter the names \n");
for(i=0;i < 3;i++)
{
scanf( "%3s",name[i]);
while(1) // loop to eat up the rest of unwanted input
{ // upto a ' ' or `\n` or `EOF`, whichever is earlier
c = getchar();
if (c == ' ' || c == '\n' || c == EOF) break;
}
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
return 0;
}
(Cringing after reading the answers to date.)
First, state the problem clearly. You want to read a line from stdin, and extract three short whitespace separated strings. The stored strings are NUL terminated and at most three characters (excluding the NUL).
#include <stdio.h>
void main(int, char**) {
char name[3][4];
printf("\n enter the names \n");
{
// Read tbe line of input text.
char line[80];
if (0 == fgets(line, sizeof(line), stdin)) {
printf("Nothing read!\n");
return 1;
}
int n_line = strlen(line);
if ('\n' != line[n_line - 1]) {
printf("Input too long!\n");
return 2;
}
// Parse out the three values.
int v = sscanf(line, "%3s %3s %3s", name[0], name[1], name[2]);
if (3 != v) {
printf("Too few values!\n");
return 3;
}
}
// We now have the three values, with errors checked.
printf("you entered these names\n%s\n%s\n%s\n",
name[0], name[1], name[2]
);
return 0;
}
you might consider something on the order of scanf( "%3s%*s",name[i]);
which should, if I recall correctly, take the first three characters (up to a whitespace) into name, and then ignore anything else up to the next white space. This will cover your long entries and it does not care what the white space is.
This is not a perfect answer as it will probably eat the middle entry of A B C if single or double character entries are mode. strtok, will separate a line into useful bits and you can then take substrings of the bits into your name[] fields.
Perhaps figuring out the entire requirement before writing code would be the first step in the process.

Resources