So I've tried so much but I can't input a string even using: fgets, gets, scanf, and scanf("%[^\n]%*c",pharse). I need a string with the spaces. It just jumps the code line of input I think.
Please answer with a explanation of why it doesn't work
https://repl.it/#YashKumar11/String#main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const int DIMMAX=100;
char pharse[DIMMAX+1];
int stringLength;
int choice=0;
while(choice != '5'){
printf("1)Enter a new pharse.");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5)\n");
scanf("%d",&choice);
switch(choice){
case 1:
printf("\n=====================\n");
scanf ("%[^\n]%*c",pharse); //<-----------------------It jumps here
printf("\n=====================\n");
stringLength = strlen(pharse);
printf("%s",pharse);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
default:
printf("\nNot a valid option.\n\n");
break;
}
}
return 0;
}
the statement to input the parase fails because the input for choice leaves a \n in the input stream.
When the second call to scanf() is made, it immediately returns (with a returned value of 0) because the first character input is \n.
suggest following each call to scanf() with:
int ch;
while( (ch = getchar()) != '\n' && ch != EOF );
that also implies that the format string of the second call to scanf() should have the %*c removed.
Your problem is not in the line that you try to read the string, but in the previous call to scanf()
scanf() was written to scanf formatted input. Keyboard input is not that. It can be everything except formatted. The user has over 100 keys to choose from
When the user types a '1' to input a phrase scanf() does not consume the newline. In fact the user can type 1 here we go to enter some text!
and then ENTER. And scanf() will be ok with just the '1'. The rest of the chars would be left there for the program to read. scanf() has no way to know what is left there.
Also scanf() return an int with the number of values read, and it can be zero if the user entered no digits. And you did not tested in your code.
Compare with your code a bit modified below
#define DIMMAX 100
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char phrase[DIMMAX + 1];
int stringLength;
printf("1) Enter a new phrase");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5) Exit\n\nOption: ");
fgets(phrase, DIMMAX, stdin);
while (phrase[0] != '5')
{
switch (phrase[0]) {
case '1':
printf("\n=====================\n");
fgets(phrase, DIMMAX, stdin);
printf("\n=====================\n");
stringLength = strlen(phrase);
phrase[strlen(phrase) - 1] = 0; // deletes the '\n'
printf("Phrase: '%s', len = %zd\n\n", phrase, strlen(phrase));
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
default:
printf("\n'%c' (dec %d) is not a valid option.\n\n",
phrase[0], phrase[0]);
break;
}
printf("1) Enter a new phrase");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5) Exit\n\nOption: ");
fgets(phrase, DIMMAX, stdin);
}; // while()
return 0;
}
Maybe it helps to understand.
Note that instead of stopping rigth at the digit, like scanf(), fgets() read up to and including the newline, so if you are using printf() and not puts() to output it, you must take the last byte off the string read
Related
This question already has answers here:
How to clear input buffer in C?
(18 answers)
Closed 5 years ago.
I have attached output image of my program. you can see the problem i am facing by clicking here
Below code is my program to read an input from an user as character and check whether it is an alphabet or an number using my_isalpha() and my_isalnum() functions of my own versions of built in function isalpha() and isalnum().
Not working for second iteration of while loop
#include <stdio.h>
#define NUM 1
#define ALPHA 2
#define ASCII 3
#define BLANK 4
int main()
{
char option;
do
{
//declaration of function
char character;
int user_option, status;
//get the character from the user
printf("Enter the Character:");
//clears both buffers to read the character
fflush(stdin);
fflush(stdout);
//reads one character at a time
character = getchar();
//prompt the user for the option to check
printf("Choice Below Option\n");
printf("1.isalnum\n2.isalpha\n");
printf("Enter your Option:");
scanf("%d", &user_option);
//validation of the user_option
switch(user_option)
{
case 1:
status = my_isalnum(character);
if(status == NUM)
{
printf("Character '%c' is an number", character);
}
else
{
printf("Character '%c' is not a number", character);
}
break;
case 2:
status = my_isalpha(character);
if(status == ALPHA)
{
printf("Character '%c' is an Alphabet", character);
}
else
{
printf("Character '%c' is not Alphabet",character);
}
break;
default:
puts("Invalid Choice.....");
}
printf("\nDo you want to continue?[Y/N]:");
scanf(" %c", &option);
}while (option == 'Y' || option == 'y');
fflush(stdin);
fflush(stdout);
return 0;
}
//Function chaecks for the Number
int my_isalnum(char character)
{
return (character >= '0' && character <= '9')? NUM : -1;
}
//functionn checks for the alphabets
int my_isalpha(char character)
{
return (character >= 'a' && character <= 'z' || character >= 'A' && character <= 'Z') ? ALPHA: -1;
}
above code works properly for the first time but during second iteration of while loop. when I give "Y" as an input code dirrectly jumps to user_option part of scanf .rather then waiting for "getchar()"- function.
Even after filushing the buffer using fflush() function i am not able to prompt the program for the character input.
Flushing stdin is undefined behavior. Flushing is meant for output stream not input stream.
As per standard ยง7.21.5.2
If stream points to an output stream or an update stream in which the
most recent operation was not input, the fflush function causes any
unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.
Also int getchar(void) : get char() returns an int.
Quickfix: Remove fflush(stdin) from code.
printf("\nDo you want to continue?[Y/N]:");
scanf(" %c", &option);
getchar(); // this dummy getchar() will consume the `\n` from stdin.
}while (option == 'Y')
Note:
Also as other solutions suggest to use fpurge() is an option but again it is non-standard and non-portable.
Here
//clears both buffers to read the character
fflush(stdin);
fflush() doesn't clear stdin buffer as you expected. fflush() is for flushing output stream like stdout not input stream stdin.
To resolve this issue one way is to use extra getchar() to consume \n character. for example
scanf(" %c", &option);
getchar(); /* dummy getchar */
Also here
char character; /* change the type of character to int */
character = getchar();
getchar() return type is of int not char, you need to change the type of character. From the manual page of getchar()
int getchar(void);
Here is my code:
#include <stdio.h>
#include <stdlib.h>
enum abcd{aaaa,bbbb,cccc,dddd,z};
typedef struct stct{
abcd eAbcd;
int x;
} stct;
typedef struct indexx{
int size;
struct stct *addr;
} indexx;
void add_item(indexx *idx);
stct read_in();
int main()
{
indexx idx = {0, NULL};
int op;
while (1)
{
printf("\n1. add item\n4. quit\n");
scanf("%d\n", &op);
switch (op)
{
case 1:
add_item(&idx);
break;
case 4:
return 0;
default:
printf("Please enter a correct number\n");
}
}
}
void add_item(indexx *idx)
{
stct *newdata;
newdata = (stct *) realloc(idx->addr, idx->size*sizeof(stct));
if (newdata)
{
idx->size ++;
idx->addr = newdata;
idx->addr[idx->size-1] = read_in();
}
else
printf("No memory\n");
}
stct read_in()
{
stct temp;
int ab;
temp.eAbcd = z;
while (temp.eAbcd != aaaa && temp.eAbcd != bbbb && temp.eAbcd != cccc && temp.eAbcd != dddd)
{
printf("select(1-4):\n");
scanf("%d", &ab);
ab-=1;
switch (ab)
{
case 0: temp.eAbcd = aaaa; break;
case 1: temp.eAbcd = bbbb; break;
case 2: temp.eAbcd = cccc; break;
case 3: temp.eAbcd = dddd; break;
}
}
scanf("%d", &temp.x);
return temp;
}
It was supposed to print out select(1-4): before scanf(), but when I compile and run the program, I got this:
1
select(1-4):
(1is what I entered.)
I have tried the solutions in C/C++ printf() before scanf() issue and none of them works for me.
Your problem is in this line:
scanf("%d\n", &op);
The \n here is just a whitespace character (like and \t) and scanf() treats any whitespace character the same: They match a sequence of whitespace in the input stream of any length (including 0).
If you enter a number and hit enter, you do enter a newline and this newline is indeed matched by \n, it would also be matched by or \t. But you don't want to match it: stdin is by default line buffered, and as scanf() would optionally match more whitespace characters, it will wait for more input to see whether more whitespace is following and only return once you hit enter again because with line buffering, input only becomes available at a newline.
In a nutshell: This scanf() won't complete until you hit enter again, so add_item() isn't even called until you do.
The simple solution here: remove the bogus \n from the format string.
I have a problem with the input for a postfixed notation calculator in C.
My teacher asked me to use scanf("%s",token) to get the input. To stop reading tokens, I check if the value returned by scanf is EOF. It works if I use input redirection when testing, but if I write the expression on the Windows cmd I fall into an endless loop. How can I stop scanf when I simply press enter without entering a string?
Here's the code:
#include <stdio.h>
#include <ctype.h>
#include "stack.h"
int main(){
int a,b,t,stop;
char token[10],c;
do{
stop = scanf("%s",token);
if (stop == EOF){
break;
}
if (isdigit(token[0])){
t = atoi(token);
push(t);
}else{
a = top();
pop();
b = top();
pop();
c = token[0];
switch(c){
case '+': t = a + b;
break;
case '-': t = a - b;
break;
case '*': t = a * b;
break;
case '/': t = a / b;
break;
}
push(t);
}
} while(1);
printf("Result: %d\n",top());
}
The problem is in the if block after the stop variable inizialisation, I think. Sorry for my English, I'm an Italian student, I tried to be as neat as I can.
"How can I stop scanf when I simply press enter without entering a string?"
Using scanf() to read '\n' (Enter) is challenging. fgets() or fgetc() is a better approach. But the following shows how to nearly do it with scanf().
The %s in scanf("%s",token); first consumes leading white-space including '\n'. Code must first detect any potential '\n' before calling scanf("%s",token);.
char ws[2];
// Consume white-space, but not \n
scanf("%*[ \f\r\t\v]"); // Depending on locale, this may not be a complete list
if (1 == scanf("%1[\n]", ws) {
break;
}
stop = scanf("%s",token);
if (stop == EOF){
break;
}
A cleaner way to do this.
int ch;
while (isspace(ch = fgetc(stdin)) && ch != '\n');
if (ch == '\n') {
break;
}
ungetc(ch, stdin);
stop = scanf("%s",token);
if (stop == EOF){
break;
}
Only one more question: to stop the program, I had to type ctrl+z
twice. Can you tell me why?
Usually the C standard input in line buffered text mode is implemented by calling a system specific function which reads a line and returns the number of characters in it (including the newline character); when the number 0 is returned, this is considered EOF. Now, when you enter "3 5 +(crtl+z)(ctrl+z)", the first Ctrl-Z ends the input line and causes the reading function to return 5, but this does not indicate EOF to the standard input functions; only after the second Ctrl-Z ist pressed without intervening input, 0 is returned and recognized as EOF.
I wrote a C program wherein I am accepting a numeric input from the user. However, if the user inputs a character, then I have to show that it is an invalid input and make the user enter a number again. How do I achieve this? I am writing the program using gcc compiler in Ubuntu. The search results on Google suggest to use isalpha function...however, it is not available in the libraries I guess.
I also tried the below...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void main()
{
system("clear");
if (isdigit(1))
printf("this is an alphabet\n");
else
printf("this is not an alphabet\n");
}
You will need to use scanf to get user input with %d as you want to scan an integer. In your case, scanf will return 1 on sucessfull scanning.
int num;
//loop to prompt use to enter valid input
while(scanf("%d",&num)==0) //scanning an integer failed
{
printf("invalid input ! Try again\n");
scanf("%*s"); //remove the invalid data from stdin
}
The functions isalpha() and isdigit() works when you are getting a character input using %c in the scanf. If you want to scan input using %c , then you can simply check like what you have done in your code provided that you get input using %c. Note that character 1 ('1') is note equal to integer 1 . Characters have their integer values as represented by the ASCII table. Your program to prompt the user again when the user enters anything other that a number using %c will look like this:
char ch;
while(1){
printf("Enter a number\n");
scanf(" %c",&ch);
printf(Your input is %c\n",ch);
if(isdigit(ch))
{
printf("This is a number\n");
break;
}
else
printf("This is not a number. Invalid input\n");
}
I tried the below code which worked fine..using isdigit()
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
void main()
{
system("clear");
char str[1];
printf("Enter a number\n");
scanf("%s",str);
printf("What you entered was %s\n",str);
if(isdigit(str[0]))
printf("this is not an alphabet\n");
else
printf("this is an alphabet\n");
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include<ctype.h>
int main()
{
char c;
printf("Enter a character: ");
scanf("%c",&c);
bool check=true;
while(check)
{
if( (c>='a'&& c<='z') || (c>='A' && c<='Z'))
{
printf("%c is an alphabet.",c);
check=true;
break;
}
else
{
printf("%c is not an alphabet.",c);
check=false;
}
}
return 0;
}
You can write your own. It's better to check digits since there're less cases for digits.
bool isDigit(char c) {
bool rtn = false;
switch(c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
rtn = true;
break;
default:
rtn = false;
break;
}
return rtn;
}
In the following piece of code what is while loop doing (marked with "loop")?:-
int main(void)
{
char code;
for (;;)
{
printf("Enter operation code: ");
scanf(" %c", &code);
while (getchar() != '\n') // loop
;
switch (code)
{
case 'i':
insert();
break;
case 's':
search();
break;
case 'u':
update();
break;
case 'p':
print();
break;
case 'q':
return 0;
default:
printf("Illegal code\n");
}
printf("\n");
}
}
Diclaimer:The code is not complete, it's just a part of the code because of which it won't compile.
getchar() used here to eat up the extra characters entered by user and the newline character \n.
Suppose a user entered the operation code as
isupq\n // '\n' is for "Enter" button
then, scanf() would read only character i and rest of the five characters would become consumed by the statement
while (getchar() != '\n')
;
Thus for next iteration scanf() will wait for user to input a character instead of reading it from the input buffer.
while (getchar() != '\n') // loop
;
is here to clean the buffer.
The problem that this while solves is that scanf(" %c", &code); only grabs a single character from the input buffer. This would be fine, except that there's still a newline left in the input buffer that resulted from hitting 'enter' after your input. a buffer clear is needed for the input buffer. that's what the while loop does
it is a common problem with c
Here application waits for the user to press enter.
Since the for loop in the given code is a infinite looping so the while loop is checking whether the input character is \n or not. In case the the character entered is \n it then moves toward the switch case. In general sense it is waiting of return key to be pressed to confirm your input.
if you use the fgetc function you don't have to worry and check for the enter key in your infinite loop. Even if you enter more than one character it will only take the first one
int main(void)
{
char code;
for (;;)
{
printf("Enter operation code: ");
code = fgetc(stdin);
switch (code)
{
case 'i':
insert();
break;
case 's':
search();
break;
case 'u':
update();
break;
case 'p':
print();
break;
case 'q':
return 0;
default:
printf("Illegal code\n");
}
printf("\n");
}
}
scanf() usually is not a good way to scan char variables, because the Enter you press after entering the character remains in input buffer. Next time you call scanf("%c", &input) this Enter already present in buffer gets read & assigned to input, thus skipping next input from user.