Detect a new line character - c

I am reading from stdin students in a structure array. After the details are introduced for one student, i ask for another student details. if the choice is Y, i'll add the new student, if the choice is N, break. But what if the choice is simply ENTER? How can i detect the new line character? I tried with getchar(), but it skips the first reading from stdin.When i debug it doesn't stops to the first line test=getchar(), it stops to the second one.
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
struct student
{
char name[20];
int age;
};
int main()
{
struct student NewStud[5];
char test;
int count=0;
for(count=0;count<5;count++)
{
printf("Enter the details for %s student: ",count>0?"another":"a");
printf("\nName : ");
scanf("%s",NewStud[count].name);
printf("\nAge : ");
scanf("%d",&NewStud[count].age);
printf("Would you like to continue? (Y/N)");
test=getchar();
if(test=='\n')
{
printf("Invalid input. Would you like to continue? (Y/N)");
test=getchar();
}
while(tolower(test) !='n' && tolower(test) != 'y')
{
printf("Invalid input.Would you like to continue? (Y/N)");
test=getchar();
}
if(tolower(test) == 'n')
{
break;
}
if(tolower(test) == 'y')
{
continue;
}
}
getch();
}

The problem is that scanf() leaves a newline character in the input stream, you have to consume it before you'll get "valid" data in getchar().
Ex:
scanf("\n%s",NewStud[count].name);
getchar();
printf("\nAge : ");
scanf("%d",&NewStud[count].age);
getchar();
printf("Would you like to continue? (Y/N)");
test=getchar(); // Now this will work
Check out this link for more info. It's for fgets, but it's the same problem with getchar()

Of course it skips the first reading, you put it in an if statement like so: if(test=='\n')
You got all the info for that certain student and then the user pressed enter, so you go back up to for(count=0;count<5;count++) and ask for new input for a new student.
I think what you wanted to do is use a while statement instead.

You could replace
> test=getchar();
> if(test=='\n')
> {
> printf("Invalid input. Would you like to continue? (Y/N)");
> test=getchar();
> }
with
while((test=getchar()) == '\n')
{
printf("Invalid input. Would you like to continue? (Y/N)");
}

Compare test value with '\n', like this sample:
int main() {
int test;
test = getchar();
printf("[%d]\n", test);
if(test == '\n') printf("Enter pressed.\n");
return(0);
}
ps: your test must be int.

Related

How to get a input with prompt using scanf?

I am using c and I am a newbie.
I want to get a input (1 or 2 or 3) and I will give the user suggest;
printf("please do it\n");
printf("1. \n");
printf("2. \n");
printf("3. \n");
char opt;
scanf("%c"&opt");
if opt is not 1 or 2 or 3 then
printf("error\n");
printf("please re do it");
and all is in a while(true) loop until user enter the enter(new line charactor) to exit;
and how to do it?
I tried to create a function.
void get_order(char opt){
switch(opt){
case '1':break;
case '2':break;
case '3':break;
default:
printf("error\n");
printf("please re do it"):
char option;
scanf("%c",&option);
get_order(option);
}
}
but it not work.
thank you.
That is not a good approach, your code is using recursion, it will consume memory more and more while the user don't enter the correct input. Use a loop instead. Your code should look like this:
#include <stdio.h>
int main() {
printf("please do it\n");
printf("1. \n");
printf("2. \n");
printf("3. \n");
char opt;
scanf("%c", &opt); //correct scanf
scanf("%*c"); //consume the line break
while(!(opt == '1' || opt == '2' || opt == '3')) {
printf("error\n");
printf("please re do it\n");
scanf("%c", &opt); //correct scanf
scanf("%*c"); //consume the line break
}
return 0;
}

comparing strings and printing stored strings in C

I am having trouble getting this program to print the strings I enter properly. It keeps telling me that I have not entered data, even when I have. I also can't get the strings to compare to run my if statement. Thank for any help.
#include <stdio.h>
//function prototype
void enterPerson();
void enterChoice();
//global variables
char person[30];
char choice;
int main(void) {
enterPerson();
enterChoice();
printf("Please try the Precipitation Program again.\n");
return 0;
}
void enterPerson(){
// Ask for person name
printf("Please enter name:\n");
scanf("%s", &person);
//-------------------------------------------
printf("person is %s\n", person);
//-------------------------------------------
}
void enterChoice(){
//initialize choice
choice = "M";
//ask what they choose
printf("Do you choose test or rate? (Enter T for test R for rate)\n");
scanf("%c", &choice);
printf("Xchoice is: %c\n", choice);
if ((choice == 'T')||(choice == 'R')){
printf("choice is: %c\n", choice);
}
else{
printf("Incorrect or no data was input at this time\n");
}
}
As mentioned in comments, there are at least 3 problems:
scanf("%s", person); - do not take the address of char array.
scanf(" %c", &choice); - insert space to ignore whitespace.
choice = 'M'; - "M" is a string literal, while choice is char.
There is a linefeed (0xa) character left in the input buffer. You can see it by printing the choice variable after your scanf line with:
scanf("%c", &choice);
printf("c: %x\n", choice);
There are several options to get rid of this. Easiest is explained here.
Also there is a problem in:
scanf("%s", &person);
Character array name in C points to the first character, so you should fix this with:
scanf("%s", person);

Having problems with creating menu in C using do..while and if..else statement

I am new in this world of programming. I am learning programming at my school. My teacher recently ask the class to create a menu with limited selection that will end with a sentinel value.
So here's my coding:
#include <stdio.h>
void menu(void);
void choice1();
void choice2();
void choice3();
char choice;
int main() {
do {
menu();
if (choice =='1')
choice1();
else if (choice =='2')
choice2();
else if (choice =='3')
choice3();
else if (choice =='4')
break;
else
printf("Invalid character.");
} while (choice != '4');
return 0;
}
void menu(void) {
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
scanf("%c", &choice);
}
void choice1() {
printf("\nChoice 1\n");
}
void choice2() {
printf("\nChoice 2\n");
}
void choice3() {
printf("\nChoice 3\n");
}
When I try to run it, by putting the number 1, 2, 3, the output came out but after that the function menu() and also the line "Invalid character." came out. As for as the other character, the menu() and the "Invalid character" came out twice. Number 4 does end the program. Is there any improvement that I can make to make sure the menu() and the line "Invalid character." does not come out unnecessarily?
In line-buffered input, the newline character lingers in the buffer after you read a single character for 'choice' and hence you get Invalid character. unintentionally.
You are required clear the buffer after reading the choice
scanf("%c", &choice);
while(getchar()!='\n')
/* Wasting the buffer
* Hence ensuring that the character you enter
* is indeed considered for 'choice'
*/
;; // Do nothing in particular
As a side note, your program looks like a typical use-case for the switch-case command and maybe your teacher expects you to use it.
Considering the scenario mentioned by #chqrlie in [ this ] comment, the workaround is to add after
scanf("%c", &choice);
the below lines
int c;
while ((c = getchar()) != EOF && c != '\n')
;; //Wasting the buffer
The problem is simple: the terminal is line buffered: you must press enter for the input to become available to your program, the first scanf("%c", &choice) retrieves the character typed and the second call retrieves the linefeed ('\n') that was generated by the enter key.
There are multiple ways to avoid this problem. You can add a space in the scanf format before the %c: scanf(" %c", &choice); or you can read characters after the first until you get a '\n'.
Note that you must check the return value of scanf to avoid undefined behavior if the user enters an end of file. It is also advisable to avoid global variables: the function menu() should return the choice specified. Using a switch statement is also more idiomatic for this.
Here is a corrected version:
#include <stdio.h>
int menu(void);
void choice1(void);
void choice2(void);
void choice3(void);
int main(void) {
int ch;
for (;;) {
switch (ch = menu()) {
case '1': choice1(); continue;
case '2': choice2(); continue;
case '3': choice3(); continue;
case '4':
case EOF: break;
default: printf("Invalid character %c\n", ch); continue;
}
break;
}
return 0;
}
int menu(void) {
char choice;
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
if (scanf(" %c", &choice) == 1)
return choice;
else
return EOF;
}
void choice1(void) {
printf("\nChoice 1\n");
}
void choice2(void) {
printf("\nChoice 2\n");
}
void choice3(void) {
printf("\nChoice 3\n");
}
As already mentioned in other answers the problem is the newline character.
When you press 1 followed by enter, you'll get two chars, i.e. 1 and \n. So your loop runs twice and prints Invalid character when \n is processed.
Here is an alternative solution for your problem. Just add a space before %c.
scanf(" %c", &choice);
This works because the space will match any number of white-space characters and thereby match the \n and remove it.
From the man page:
A sequence of white-space characters (space, tab, newline,
etc.......). This directive matches any amount of
white space, including none, in the input.
Additional comments
You should always check the value returned by scanf to make sure you read the correct number of values.
if (scanf(" %c", &choice) != 1)
{
// Add error handling ....
// For instance you could terminate the program like
exit(1);
}
In your program choice is a global variable. In general global variables should be avoid if possible. In your case you could make choice a local variable in main and let menu return a char. Like:
// char choice; Remove global variable
int main() {
char choice; // Add local variable
do {
choice = menu(); // Assign to local variable
.....
}
char menu(void) { // Make the function return a char
char choice; // Add local variable
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
if (scanf("%c", &choice) != 1) exit(1); // Assign to local variable
// On failure -> exit
return choice; // Return value of local variable
}
You can write scanf(" %c",&choice); (with whitespace) instead of scanf("%c",&choice);
When I try to run it, by putting the number 1, 2, 3, the output came
out but after that the function menu() and also the line "Invalid
character." came out.
It's happening because of the new line character you press after each number. It's itself a character and loop is iterated one more time for this. As it is an invalid character, that's why "Invalid character." is showing.
Try using getchar() after scanf().
Edit: fixed my previous while loop which may exit incorrectedly:
#include <stdio.h>
int main() {
int choice;
printf("Menu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("2) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
while (1) {
char c = scanf("%d",&choice);
if (c == EOF || choice == 4) break;
if (choice == 1 || choice == 2 || choice == 3) {
printf("Choice %d.\n", choice);
} else {
printf("Invalid character.\n");
}
}
return 0;
}
You can use function if you want, but not necessary in this case. You need to understand how many times your loop actually runs and compare it to that you expect.
My previous code:
#include <stdio.h>
int main() {
int choice;
printf("Menu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("2) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
while (scanf("%d", &choice) && choice != 4) {
if (choice == 1 || choice == 2 || choice == 3) {
printf("Choice %d.\n", choice);
} else {
printf("Invalid character.\n");
}
}
return 0;
}

If statement not working for marital status

I am creating a program which requires user to enter their marital status.
i want to be able to ask them Yes or No and then use if statements .
my code just skips the if block and prints the else block.
#include<stdio.h>
int main(void)
{
int age;
char marr;
printf("Please enter your age: \n");
scanf_s("%d",&age);
getchar();// getchar() is being used to clear any buffer of any remaining keystrokes that might stll be stored.
printf("Are you married ? (y/n)\n");
scanf_s("%c", &marr);
if (marr == 'y')
printf("Married\n");
else
printf("Unmarried\n");
}
for some reason, whatever I input, i still get the output as unmarried,
no idea why.
Use scanf() instead of scanf_s() in this case or you'll need a buffer size argument if your input parameter is a character. Too you can place a space before %c in the scanf()-statement instead of your getchar()-command.
#include<stdio.h>
int main(void) {
int age;
char marr;
printf("Please enter your age: \n");
scanf("%d",&age);
printf("Are you married ? (y/n)\n");
scanf(" %c", &marr);
if (marr == 'y')
printf("Married\n");
else
printf("Unmarried\n");
}

if statement with nested functions will not execute

#include <stdio.h>
main()
{
char name[30];
int age;
printf("Please enter your name: ");
scanf("%s", name);
printf("How old are you %s: ", name);
scanf("%d", age);
if (strcmp(name, "Abs") == 1 && age == 25)
printf("You are the CHOSEN one!\n");
else
printf("You are a wankstain!\n");
fflush(stdin);
getchar();
}
The if statement seems to ignore the right answer, i have also tried to put the age in brackets to no avail.
Why not read the manual page for strcmp. You been to check for zero.
Ditto for scanf - it does return a value that needs to be checked.
Use braces - prevents problems in the future.
You do not need to flush stdin.
(see http://linux.die.net/man/3/strcmp and http://linux.die.net/man/3/scanf)

Resources