comparing strings and printing stored strings in C - 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);

Related

Why does C skip scanf() [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 months ago.
So I was writing a quick program to get information about a patient from a hospital and it keeps skipping the scanf() at a certain point (at around line 34) and moves on to the scanf() after it. Here's the part that keeps bothering the life out of me:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main(void){
char choice_1, choice_2, *blood_group, *spec_conditions, *allergies;
printf("Enter the patient's medical details.\n\n");
printf("Enter your blood group: ");
scanf("%s",&blood_group);
printf("Does the patient have any allergies:(y/n)");
scanf("%c",&choice_2);
if (choice_2 == 'y'){
printf("Kindly enter the allergies: ");
scanf("%s",&allergies);
}else{
allergies = "No allergies";
}
printf("\nDoes the patient have any special conditions:(y/n)");
scanf("%c",&choice_1);
if (choice_1 == 'y'){
printf("Kindly enter the condtion: ");
scanf("%s",&spec_conditions);
}else{
spec_conditions = "No special conditions";
}
printf("Displaying details...\n");
sleep(2);
system("cls");
printf("\t\t\tPATIENT DETAILS\n");
sleep(1);
return 0;
}
Problem 1:
char *blood_group, *spec_conditions, *allergies;
scanf("%s",&blood_group);
scanf("%s",&allergies);
scanf("%s",&spec_conditions);
What this does is it attempts to write a string of an unknown length to the address of char * variables, resulting in a 'buffer' overflow if the string is larger than a pointer, or a wild pointer that points to a random location.
Do not pass the address of the pointer to scanf, pass the pointer itself. Furthermore, the pointer must point to writable memory. This can be done by declaring it as an array.
Problem 2:
scanf("%c") reads the newline left when the user hits enter to read the string and moves on. Use scanf(" %c") instead to skip leading whitespace and read the actual character.
Try:
int main(void){
char choice_1, choice_2, blood_group[256], spec_conditions[256], allergies[256];
printf("Enter the patient's medical details.\n\n");
printf("Enter your blood group: ");
scanf("%255s",blood_group);
printf("Does the patient have any allergies:(y/n)");
scanf(" %c",&choice_2);
if (choice_2 == 'y'){
printf("Kindly enter the allergies: ");
scanf("%255s",allergies);
}else{
strcpy(allergies, "No allergies");
}
printf("\nDoes the patient have any special conditions:(y/n)");
scanf(" %c",&choice_1);
if (choice_1 == 'y'){
printf("Kindly enter the condtion: ");
scanf("%255s",spec_conditions);
}else{
strcpy(spec_conditions, "No special conditions");
}
printf("Displaying details...\n");
sleep(2);
system("cls");
printf("\t\t\tPATIENT DETAILS\n");
sleep(1);
return 0;
}

scanf stops working after first one [C]

I am trying to have the user enter for the first, middle, and last name in my struct. The first scan works fine, any after that do not work. Here's my code so far
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "contacts.h"
int main (void)
{
// Declare variables here:
struct Name names;
char yesNo;
// Display the title
printf("Contact Management System\n");
printf("-------------------------\n");
// Contact Name Input:
printf("Please enter the contact's first name: ");
scanf ("%d", &names.firstName);
printf("Do you want to enter a middle initial(s)? (y or n): ");
scanf(" %c", &yesNo);
while (yesNo == 'y' || yesNo == 'Y') {
printf("Please enter the contact's middle initial(s): ");
scanf(" %c%d", &names.middleInitial);
yesNo = 'n';
}
printf("Please enter the contact's last name: ");
scanf(" %c%d", &names.lastName);
Here's the struct in my header file
struct Name {
char firstName[31];
char middleInitial[7];
char lastName[36];
};
When I enter more than one character the program ends, when I enter just one character, the program skips the second scanf. I had the program working beforehand but I realized I needed to use structs so I switched from int's to the struct, and I haven't been able to make it work this way.
You are using scanf wrong.
scanf ("%d", &names.firstName);
names.firstName is a char array, but you are using %d which expects a
pointer to int, you are passing a pointer to an array. This is correct:
scanf("%30s", names.firstName);
Then you do
scanf(" %c%d", &names.middleInitial);
which has two errors: you are giving two conversion but passing only a on
pointer, and you are again passing the wrong pointer. Correct:
scanf("%6s", names.middleInitial);
and the same applies for scanf(" %c%d", &names.lastName);, the correct version
scanf("%35s", names.lastName);
In general, when using scanf with %s, you will have the problem that newline
and other strings are kept in the input buffer. This happens because %s
matches a sequence of non-white-space characters, so the newline (entered when
ENTER is pressed) will remain in the input buffer. Another example is
if the user enters two word separated by at least an empty space (like Hello Word),
%s would only read Hello. Subsequent calls of scanf may fail if they don't
anticipate this. That's why the best strategy is to clean the
buffer, use this function:
void clean_file_buffer(FILE *fp)
{
int c;
while((c = fgetc(fp)) != '\n' && c!=EOF);
}
And the you can use it like this:
printf("Please enter the contact's first name: ");
scanf ("%30s", names.firstName);
clean_file_buffer(stdin);
that takes care of left overs.
If you however want to have more control over the whole line, then you should
use fgets instead to read the whole line and then you can use sscanf to
parse it.
scanf("%s", names.firstName);
scanf(" %c", &yesNo);
scanf(" %s", names.middleInitial);
scanf(" %s", names.lastName);
or
scanf("%s", names.firstName);
getchar();
scanf("%c", &yesNo);
getchar();
scanf("%s", names.middleInitial);
getchar();
scanf("%s", names.lastName);
getchar();
and when yesNo question, if you typed over 1 character, first character will be into yesNo variable, and other chars will be into next input variable(names.middleInitial).
If you want to check the yesNo more carefully,
input yesNo as string. (but, buffer size check needed. buffer overflow.)
char yesNos[100];
scanf(" %s", &yesNos) ;
if ( yesNos[0]=='y' ) {...}

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");
}

"scanf with printf" vs "fgets with printf"

I know about the difference and the advantage/disatvantage of using scanf and fgets.
I don't understand the relations between printf and this two C standard functions.
I have this simple code:
void print_choice(char * list, char * choice)
{
/* check parameters */
if(!list || !choice)
return;
printf("list of users: %s\n", list);
printf("Choice -- ? ");
/* scanf("%s", &choice); */
/* fgets(choice, 20, stdin); */
}
int main()
{
char choice[20];
char * list = "marco:dario:roberto:franco";
print_choice(list, choice);
printf("choice = %s\n", choice);
return 0;
}
if I use fgets, printf print the result correctly on stdout;
If I use scanf, printf` doesn't print anything on stdout.
Why this behaviour?
You used scanf("%s", &choice); which passes a char ** to scanf() when it expects a char *.
Drop the &.
If your compiler wasn't complaining, you either haven't turned on enough warnings or you need a better compiler.
Change
scanf("%s", &choice);
to
scanf("%s", choice);
you have to use
scanf("%s", choice);
instead of
scanf("%s", &choice);
Changing this scanf("%s", &choice); to this scanf("%s", choice); will cause scanf and fgets to show almost similar behavior.
scanf requires an address as an argument. It goes on and stores the input from stdin after converting it based on the supplied format specifier. Here the format specifier is %s so it will try to store the input at the address pointed by address of choice . What you need here is the address from where the choice array will begin,which in this case is choice itself.

Why doesn't scanf() take inputs from the user while dealing with strings?

My code is as follows
typedef struct
{
char name[15];
char country[10];
}place_t;
int main()
{
int d;
char c;
place_t place;
printf("\nEnter the place name : ");
scanf("%s",place.name);
printf("\nEnter the coutry name : ");
scanf("%s",place.country);
printf("\nEnter the type of the place : Metropolitan/Tourist (M/T)?");
scanf("%c",&c);
printf("You entered %c",c);
return 0;
}
If I run the program, it prompts for place name and country name, but never waits for the character input from user.
I tried
fflush(stdin);
fflush(stdout);
Neither work.
Note : Instead of a character, if I write a similar code to get an integer or a float, it prompts for values and the code works just fine.
int d;
printf("\nEnter the type of the place : Metropolitan/Tourist (M/T)?");
scanf("%d",&d);
Why does this happen? Is there anything wrong in the code?
The problem is that scanf leaves the whitespace following entered non-whitespace characters in the stream buffer, which is what the scanf(%c...) then reads. But wait a second...
In addition to being tricky to get right, such code using scanf is horribly unsafe. You're much better off using fgets and parsing the string later:
char buf[256];
fgets(buf, sizeof buf, stdin);
// .. now parse buf
fgets always gets a full line from the input, including the newline (assuming the buffer is large enough) and you thus avoid the problem you're having with scanf.
You can use string instead of character for scanf.
printf("\nEnter the place name : ");
scanf("%s%*c",place.name);
printf("\nEnter the coutry name : ");
scanf("%s%*c",place.country);
printf("\nEnter the type of the place : Metropolitan/Tourist (M/T)?");
scanf("%c",&c);
printf("You entered %c",c);
Try adding spaces before the % sign in scanf().
I have provided the modified code below.
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[15];
char country[10];
} place_t;
int main()
{
int d;
char c;
place_t place;
printf("\nEnter the place name : ");
scanf(" %s",place.name);
printf("\nEnter the coutry name : ");
scanf(" %s",place.country);
printf("\nEnter the type of the place : Metropolitan/Tourist (M/T)?");
scanf(" %c",&c);
printf("You entered %c",c);
return 0;
}

Resources