I have the following code:
#include <stdio.h>
int opt;
scanf("%d",&opt);
while(opt!=0)
{
switch(opt)
{
case 1:func1();
break;
case 2:func2();
break;
case 3:return 0;
}
printf("\n");
scanf("%d",&opt);
}
I want to computer to get from user everytime different digit (1 or 2 or 3) and in every time the computer will run on seperate function. but when I press 2, func2 gets 3 ints and prints chars on the screen in a new line. the computer reads them instead of reading next input (1 or 2 or 3). how can I fix it?
EDIT: The problem rises only after specific inputs (I build a program converts bases).
Input:
2
10
26
1z2
OUTPUT:
ERROR
INPUT:
2
38762
10
UNWANTED OUTPUT:
201222
I'm not sure from where the computer scans the second num it uses to print the last unwanted output.
your second scanf is supposed to block but it isn't because the input buffer is not empty after the first call! This is why it is always returning the previous value and looping infinitely.
Use a combination of fgets and sscanf instead.
Also check this : http://c-faq.com/stdio/scanfprobs.html
If your functions use scanf() inside them to ask for characters or you are using fgets() to read a while line, you might find that scanf() / fgets() does run without user input. This is because the newline character you entered at scanf("%d",&opt); is still there and is used as new input for the next scanf()/fgets(). You have to erase it by issuing
fflush (stdin);
Just prior to call scanf() or fgets()
you may need something like this..
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
int opt;
do{
printf("Enter the option\n");
scanf("%d",&opt);
switch(opt){
case 1: func1();
break;
case 2: func2();
break;
case 3:
return 0;
}
}while(opt != 3);
return 0;
}
One problem that is pointed out by hhachem in comment that you are not exiting from your while loop.
You can solve this problem by doing (as you want to exit only after pressing 3):
while(1)
{
switch(1)
{
case 1:func1();
break;
case 2:func2();
break;
case 3: exit(0);
}
printf("\n");
scanf("%d",&opt);
}
Test program:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int opt;
scanf("%d",&opt);
while(1)
{
switch(opt)
{
case 1:printf("1");
break;
case 2:printf("2");
break;
case 3:exit(0);
}
printf("\n");
scanf("%d",&opt);
}
return 0;
}
See the output.
Related
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
I have this program show, which allows me to display a menu with 3 choices. If you choose anything except exit (0) then the program continues to loop.
However, when I try to call a function from inside the switch statement, once the function is finished, the loop exists completely. I want to go back to the menu and continue unless I select exit.
The program works, without the function call.
It also works if I select 2, triangle, it then stays in the loop.
Why is this happening, and how can I fix it,
many thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int rows;
void xmasTree(void)
{
printf("Enter Rows:\n>");
scanf("%d",&rows);
}
int main (int argc, char ** argv)
{
int flag = 1;
while (flag)
{
//Print menu
printf("1: Create xmas tree\n");
printf("2: Create triangle\n");
printf("0: exit\n");
printf("Enter choice :");
//read input
char buffer[10];
fgets(buffer, 10, stdin);
//convert to number
int number = atoi (buffer);
//work on input
switch (number)
{
case 1:
printf("Building your xmas tree\n");
xmasTree();
break;
case 2:
printf("creating your triangle\n");
break;
case 0:
printf("Exiting...\n");
flag = 0;
break;
default:
printf("INVAID INPUT\n");
break;
}
}
return 0;
}
The problem is, that here
scanf("%d",&rows);
you read a number from stdin, but you leave the trailing newline inside the stream!
Then, in the next loop iteration
fgets(buffer, 10, stdin);
reads the (empty) line and
int number = atoi (buffer);
sets number to 0, causing your program to exit.
One possible fix would be to read in rows with fgets() and atoi() as you do it with number.
The problem is this call in the function xmasTree
scanf("%d",&rows);
After it there is stored the new line character '\n' in the buffer. So the next call of the function fgets reads an empty string. You should remove this new line character as for example
scanf("%d",&rows);
scanf( "%*[^\n]" );
scanf( "%*c" );
I'm having a problem understanding how to get my while loop to simply output a message saying "Invalid Input" and asking for a new question from the user unless he chooses number 1 or 2 in the list. What happens if you for example input : asdas instead of a integer the program never stops looping.
What I would like to happen is for the program to tell the user to enter a new number from 1-2 instead of simply stopping running which i can achieve by setting the default in the switch to exit(0); or runSystem = false;
For example:
CMD Says enter 1-2 the user enters : asdaf (never stops looping) as in current situation.
What I want is: asdf and then it says "enter a new choice" and waits for a correct answer.
What bothers me is the fact that the program will do as i want it to if you enter an invalid number for example: 12312312 and ask for a new entry but it doesn't work with string input.
Code:
#include <stdio.h>
#include <stdbool.h>
int main(int argc, char **argv) {
int userinput;
int runSystem = true;
void options() {
printf("<========Welcome to the program, please make a choice========> \n\n");
printf("1: Say Hello\n");
printf("2: Say GoodBye\n");
printf("Please enter a choice:");
scanf("%d", &userinput);
}
while (runSystem) {
options();
switch(userinput) {
case 1: printf("Hello!\n");
break;
case 2: printf("GoodBye!\n");
break;
case 3: printf("Invalid, try again\n");
break;
default:
break;
}
}
return 0;
}
scanf("%d", &userinput); expects an int as the input. When you give a non-integer, scanf() won't assign it to userinput.
Check the return value of scanf() to see if it was successful. It returns the number of successful assignments it did.
When you give a string as input, scanf() won't accept it and will leave it in the input buffer unconsumed.
When you do scanf() again, the invalid input is still present in the input buffer and that is what the second scanf() tries to read. The same thing happens and this goes on. This is the reason behind your infinite loop.
To overcome this, you should consume the invalid input from the input buffer after displaying the message in case 3. Do something like
int ch;
while( (ch=getchar())!='\n' && ch!=EOF );
This will consume from the input buffer till a \n is encountered. getchar() return EOF on failure.
Edit: Standard C doesn't allow nested function definitions. The reason why you didn't get an error for that is probably because your compiler allows this as an extension. But it may not work for other compilers.
See this and this.
You could place the definition of options() within the while loop calling it or get the value for userinput as a return value or via a pointer to the variable passed to the function.
Valid C compiler does not allow declaration of the function options inside the main.
Make that function returning your input and pass the returning value to the switch. Also in order to stop the while loop case 2: should change the runSystem to false;
input : asdas instead of a integer the program never stops looping.
This is because when scanf("%d", &userinput); failed it did not updated the variable userinput.
Check the standard 7.21.6.4 The scanf function.
You can read about behaviour of scanf
here.
On success, the scanf returns the number of items successfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens. In the case of an input failure before any data could be successfully read, EOF is returned.
Knowing that you can check the return value of scanf and make appropriate decision. Presented solution eats the bad characters.
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int options(void) {
int c;
int ret;
int x = 0;
int error = 0;
printf("<========Welcome to the program, please make a choice========> \n\n");
printf("1: Say Hello\n");
printf("2: Say GoodBye\n");
printf("Please enter a choice:");
while(1)
{
c = '0';
if(!error)
printf("Input a number:\n");
else
error = 0;
ret = scanf("%d", &x);
if(ret == EOF) {
return 2; // END OF PROGRAM
}
else
{
if (ret == 1){
return x;
}
else // NOT a number
{
printf("No letters! Input a number:\n");
do
{
c = getchar();
if(c == EOF)
return 2; // END OF PROGRAM
}
while (!isdigit(c) && c!='\n');
ungetc(c, stdin);
error = 1;
}
}
}
}
int main(void) {
int userinput;
int runSystem = true;
while (runSystem) {
userinput = options();
switch(userinput) {
case 1: printf("Hello!\n");
break;
case 2: printf("GoodBye!\n");
runSystem = false;
break;
default:
case 3: printf("Invalid, try again\n");
break;
}
}
return 0;
}
Output:
<========Welcome to the program, please make a choice========>
1: Say Hello
2: Say GoodBye
Please enter a choice:Input a number:
X
No letters! Input a number:
a
No letters! Input a number:
1
Hello!
<========Welcome to the program, please make a choice========>
1: Say Hello
2: Say GoodBye
Please enter a choice:Input a number:
7
Invalid, try again
<========Welcome to the program, please make a choice========>
1: Say Hello
2: Say GoodBye
Please enter a choice:Input a number:
2
GoodBye!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct st{
char n[100]; //Name
char d[100]; //lastname
} arr[4];
void add(int *c, struct st l[])
{
int i =*c;
int arrSize =sizeof(arr) / sizeof(arr[0]);
if((*c)<arrSize)
{
printf("Enter a name :\n");
fgets(l[i].n, 100,stdin);
printf("Enter lastname :\n");
fgets(l[i].d,100,stdin);
printf(" SUCCESS. Person was added\n");
}
}
int main(void)
{
int ct =0;
int *ctPointer=&ct;
char response ;
char endWhileloop =0;
while(endWhileloop==0)
{
printf("To add a person to the list hit 'a' \n");
printf("to end program enter 'q'\n");
fgets(&response,2,stdin);
fseek(stdin,0,SEEK_END);
switch(response)
{
case 'a':
add(&ct, arr);
break;
case 'Q':
endWhileloop=1;
break;
}
}
printf("\nbye.");
return 0;
}
I am trying to run my code in an older version of Vim(maybe an older version of C) for my school. Unfortunately I am not certain what version they are running
Surprisingly, my code works from home using vim and eclipse. but not from school
:I tried---> fgets, scanf("%[^\n]s",name) , scan( %c,&name), fseek(stdin,0,SEEK_END),flush(stdin);
But nothing has worked for me. I would like to know of some possible solutions.
When I run my code from school(not home), after I enter 'a' my code prints: Enter name..(line in between) Enter last name.
Without taking an input.
Place this line instead of fseek
After getting the option you are not clearing the input buffer. so this is the reason for the not getting the first input.
After entering the first input new line will be there in input buffer. After processing first input then buffer will give the \n.
So place this line after getting the option. Declare the variable int c;
while((c=getchar()) != '\n' && c!= EOF );
Then make the case into like this,
case 'a': case 'A':
...
...
case 'q': case 'Q':
...
...
For getting the option you can use simply the scanf like this.
scanf(" %c",&response);
My goal is to produce a program that will take a file as input and "encode" the text within by shifting the characters ahead 3 (so 'a' would be come 'd'). It should produce an output file with the encoded text. The menu is to take user input and execute the function that is assigned to the number selected.
I'm early on at creating this program, but running short on time and am struggling with how to structure it. Currently, I have the menu displaying, but when a sub function is called, it displays but then the menu overwrites it and I can't figure out why. Any help would be appreciated. Here is the code I have so far...
#include <stdio.h>
#define INPUT_FILE 1 //define statements
#define OUTPUT_FILE 2
#define NUM_TO_SHIFT 3
#define ENCODE 4
#define QUIT 0
int menu(); //function prototypes
int input();
int output();
int shift();
int encode();
void quit();
int main()
{
int choice; // main variables
char user_filename[100];
choice = menu(); // get user's first selection
while(choice != QUIT) //execute so long as choice is not equal to QUIT
{
switch(choice)
{
case INPUT_FILE:
printf("Enter the filename of the file to encode:\n");
printf("(hit the Enter key when done)\n");
gets(user_filename);
break;
case OUTPUT_FILE: output();
break;
case NUM_TO_SHIFT: shift();
break;
case ENCODE: encode();
break;
case QUIT: quit();
break;
default: printf("Oops! An invalid choice slipped through. ");
printf("Please try again.\n");
}
choice = menu(); /* get user's subsequent selections */
}
printf("Bye bye!\n");
return 0;
}
int menu(void)
{
int option;
printf("Text Encoder Service\n\n");
printf("1.\tEnter name of input file (currently 'Secret.txt')\n");
printf("2.\tEnter name of output file (currently not set)\n");
printf("3.\tEnter number of characters data should be shifted (currently +7)\n");
printf("4.\tEncode the text\n\n");
printf("0.\tQuit\n\n");
printf("Make your selection: ");
while( (scanf(" %d", &option) != 1) /* non-numeric input */
|| (option < 0) /* number too small */
|| (option > 4)) /* number too large */
{
fflush(stdin); /* clear bad data from buffer */
printf("That selection isn't valid. Please try again.\n\n");
printf("Your choice? ");
}
return option;
}
int input()
{
}
int output()
{
return 2;
}
int shift()
{
return 3;
}
int encode()
{
return 4;
}
void quit()
{
printf("Quiting...Bye!");
exit(0);
}
You shouldn't use gets(user_filename) to get the file name since gets() reads up to a \n and stops reading. Your scanf for the menu option does not read the \n at the end of the line when the user types in the menu option. Essentially, you're making gets read a string without words in it. The line you want to read is actually the next line. Using scanf instead of gets will fix it.
Otherwise, your program is working as expected - it's just that your functions don't do anything yet that your menu is "overwriting" the submenus. See http://ideone.com/F2pEs for an implementation with scanf instead of gets.
use getchar(); soon after the gets(user_filename); it will wait to get the character
gets(user_filename);
getchar();
break;
As in this question which Stackoverflow has highlighted as a match, you need to clear out the buffer to remove the newline that's waiting in there.
Add this code after reading a valid menu option:
do
{
c = getchar();
} while (c != EOF && c != '\n');
where c is a char declared up by option. This loops over remaining characters in the input stream until EOF (End Of File) or a newline character is reached, meaning they don't affect your call to gets(). Note that gets() is considered insecure because it doesn't protect against buffer overflow, a user could easily enter more than 100 characters (inc. newline) and start writing into memory that shouldn't be touched by their input. You would do well to lookup the secure equivalent when you see compiler warnings around function calls like this, typically they take a second parameter which is the maximum size of the buffer being read into.
Well, this answer is way late but having come across it, I can't help but write something.
Let's get straight to it. You will have an array of menus, with the array elements being the options you want in your menu. Then while in a truthy condition, loop through the elements of the array, selecting the option you want.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//function prototypes
int input();
int output();
int shift();
int encode();
void quit();
int main(){
int menus_on = 1;
const char *menus[5] = {"Input","Output","Shift","Encode","Quit"};
while(menus_on){
int menu,*temp;
for(int i =0;i<6;i++){
printf("%d: %s\n",i,menus[i]);
}
printf("Select menu\n");
scanf("%d",temp);
menu = *temp;
printf("Selected menu::%d\n",menu);
switch(menu){
case 0:
input();
break;
case 1:
output();
break;
case 2:
shift();
break;
case 3:
encode();
break;
case 4:
quit();
break;
default:
printf("Invalid selection\n");
break;
}
}
return 0;
}
int input() {
return 0;
}
int encode () {
return 0;
}