Non-NULL User input - c

I'm trying to understand the whole concept of pointers, structures, etc so I've created a program that gets user input for two different books and then swaps the info of the two books. I had no trouble doing that, however, a problem arose- when I pressed enter the name of the book would be plain blank and at the output I would, of course, see a blank space. My problem is, how am I able to limit the user to input any letter (A-Z, a-z) and not blank space?
A string of characters when input to an array, they get saved in consecutive memory addresses. We also know that 'NULL' is represented as '\0' in arrays.
With the above things in mind, I performed multiple tests in which, ALL of them failed to yield the desired results.
Below are some attempts that I made.
1st Attempt
while (pBook1->name[0] == '\0')
{
printf("\n Please enter a valid book name: ");
fgets(pBook1->name, MAX, stdin);
}
2nd Attempt
while (strcmp(pBook1->name, ""))
{
printf("\n Please enter a valid book name: ");
fgets(pBook1->name, MAX, stdin);
}
Also, consider the following code as the source code of my program:
#include <stdio.h>
#include <string.h>
#define MAX 50
struct Books
{
char name[MAX];
int ID;
float price;
};
void swap(struct Books *, struct Books *);
void main()
{
struct Books Book1, Book2, *pBook1, *pBook2;
pBook1 = &Book1;
pBook2 = &Book2;
// Input for the 1st book
printf("\n 1st Book \n ------------------------------");
printf("\n Enter the name: ");
fgets(pBook1->name, MAX, stdin);
while (pBook1->name[0] == '\0')
{
printf("\n Please enter a valid book name: ");
fgets(pBook1->name, MAX, stdin);
}
printf("\n Enter the ID: ");
scanf("%d", &pBook1->ID);
printf("\n Enter the price: ");
scanf("%f", &pBook1->price);
// Input for the 2nd book
printf("\n 2nd Book \n ------------------------------");
printf("\n Enter the name: ");
fgets(pBook2->name, MAX, stdin);
while (pBook2->name[0] == '\0')
{
printf("\n Please enter a valid book name: ");
fgets(pBook2->name, MAX, stdin);
}
printf("\n Enter the ID: ");
scanf("%d", &pBook2->ID);
printf("\n Enter the price: ");
scanf("%f", &pBook2->price);
printf("\n Let's swap the info of the two books...");
swap(pBook1, pBook2);
printf("\n The info of the two books is now:");
printf("\n------------------------------ \n 1st Book \n ------------------------------------");
printf("\n Name \t\t ID \t Price \n %s \t\t %d \t %f", pBook1->name, pBook1->ID, pBook1->price);
printf("\n------------------------------ \n 2nd Book \n ------------------------------------");
printf("Name \t\t ID \t Price \n %s \t\t %d \t %f", pBook2->name, pBook2->ID, pBook2->price);
}
void swap(struct Books *pB1, struct Books *pB2)
{
char temp[MAX];
strcpy(temp, pB1->name);
strcpy(pB1->name, pB2->name);
strcpy(pB2->name, temp);
int tempID = pB1->ID, tempPrice = pB1->price;
pB1->ID = pB2->ID;
pB2->ID = tempID;
pB1->price = pB2->price;
pB2->price = tempPrice;
}

fgets reads until it encounters EOF, \n or N-1 bytes have been read. So if a user of your program presses enter, it will read \n and stop. Which means that pBook1->name[0] == '\n'. That is why your check for equality with "" fails and why pBook1->name[0] == '\0' fails.
See this example.
That means that you need to check for \n and \0 in case the user entered Ctrl-D which is how you enter EOF on *nix systems.

When you press enter pBook1->name[0] will become \n. You can use some functions as strlen to be sure there something in name.

Related

How to prompt inputs one by one in C?

I'm quite new to C programming and I have an issue with how the code prompts the input. I need the inputs under the input statement to come one by one.
Now the way the prompts are output is:
To add a new task enter the details below
Name of Task: Science
Then all the other inputs come as a group
Category of Task:
Information about task:
Due Date of Task:
Status of Task
TD = To-Do
IP = In Progress
CT = Completed Task
Enter Status:
But I want to it ask for the name of the task first and once I input that information, it should ask the category
For example:
To add a new task enter the details below
Name of Task:
This is my code:
#include<stdio.h>
int main() {
char main_choice;
printf("Welcome to your Task Management System\n");
printf("What would you like to do today?\n A: Add New Task\n B: View Task \n C: Manage Tasks\n");
printf("\nEnter your choice:");
scanf("%c", &main_choice);
if (main_choice == 'A'){
char name;
char category;
char info;
char date;
char status;
printf("\nTo Add a new task enter the details below\n");
printf("Name of Task:");
scanf(" %c", &name);
printf("\nCategory of Task:");
scanf(" %c", &category);
printf("Information about task:");
scanf(" %c", &info);
printf("Due Date of Task:");
scanf(" %c", &date);
printf("Status of Task\nTD = To-Do\nIP = In Progress\nCT = Completed Task\n Enter Status:");
scanf(" %c", &status);
}
return 0;
}
When using scanf in C you should put a whitespace before the %c like this:
scanf(" %c", &name);
It is required to put space before %c to skip the white space in buffer memory.
so that %c matches the character given instead of the space char.

Program producing a bus error when reading in using scanf - C Program

I'm writing a program for an employee database and I'm writing the function to add an employee. I'm getting a bus error after my final prompt to scan in info. I'm pretty sure its to do with my scanf statement as I have a print statement right after that is not printing. Why would I be getting this error?
The prompt in question is for reading in job title.
void addEmployee(void)
{
char *name;
char gender;
int age;
char *title;
printf("Enter name: \n");
scanf(" %100s", name);
scanf("%*[^\n]%*c");
printf("Enter gender: \n");
scanf(" %1c", &gender);
scanf("%*[^\n]%*c");
printf("Enter age: \n");
scanf(" %d", &age);
scanf("%*[^\n]%*c");
printf("Enter job title: \n");
scanf(" %100s", title);
scanf("%*[^\n]%*c");
printf("Test");
printf("The employee you've entered is: %s %c %d %s \n", name, gender, age, title);
Employee newEmp = {*name, gender, age, *title};
if(employeeList[0] == NULL)
{
employeeList[0] = &newEmp;
nodeCount++;
}
}
Code is passing in an uninitialized pointer.
char *name; // Pointer 'name' not initialize yet.
printf("Enter name: \n");
// 'name' passed to scanf() is garbage.
scanf(" %100s", name);
Instead, pass a pointer to an existing array
char name[100 + 1];
printf("Enter name: \n");
// Here the array 'name' coverts to the address of the first element of the array.
// scanf receives a valid pointer.
scanf("%100s", name);

string with ints and chars - C

#include <stdio.h>
#include<stdlib.h>
int main()
{
char first[10], last[10], id[10];
int stdnum;
FILE *fptr;
fptr = fopen("C:\\c\\program.txt","w");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
else
{
//first name
printf("Enter name: ");
scanf("%s", first);
fprintf(fptr,"%s ",first);
//last name
printf("Enter last name: ");
scanf("%s ", last);
fprintf(fptr,"%s", last);
//id
printf("Enter id: ");
scanf("%s %d", id, &stdnum);
fprintf(fptr,"%s\n", id);
fprintf(fptr,"%d\n", stdnum);
fclose(fptr);
return 0;
}
}
I am writing a program that asks user for name, last name and student number. Student number format is lowercase letter followed by 8 digits.
when i run this code, I can enter first and last name. After i enter last name and hit enter in cygwin, the console gives me a blank line and I MUST type atleast a charcter or a number into it for it to display "enter student id".
Enter name: bob
Enter last name: jones
1
Enter id: a00998877
then the file output is something like this:
"bob jones11"
I want the output to be something like this:
"Bob Jones a00998877"
What am i doing wrong?
Why are you scanning in two inputs in this line:
scanf("%s %d", id, &stdnum);
id is a char array and will be able to hold alphanumeric input. You can remove the use of stdnum.
scanf("%s", id);
I have an example-with-stdin-stdout
char first[10], last[10], id;
id is a single char no need for an array.
scanf("%s", last);
Removed space after s
scanf(" %c%d", %id, &stdnum)
changed id to char from string
fprintf(fptr,"%c\n", id)
Same here, changed to char

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

C prompt ordering for reading string with getchar() [duplicate]

This question already has answers here:
Why is getchar() reading '\n' after a printf statement?
(3 answers)
Closed 9 years ago.
This is a newbie question. I am new to C programming. I have the following code which does not prompt for 'Name' Onece the 'Age' is entered, it bypass the 'Name section.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
printf("Enter age : ");
scanf("%d", &age);
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
After reading first prompt it bypass the second prompt which is using getchar() function. But if I change the order of prompt to ask for 'Name' first and then 'Age' it works fine.
The working code.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Enter age : ");
scanf("%d", &age);
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
My coding IDE is CodeBlock and my compiler is GNU C Compiler (mingw32-gcc.exe)
Please help me to breakthrough.
A few improvements/advices to the code in the question:
the type of the return value of getchar() is int, so the type of ch also should be int
you could (and should, I believe) use format %s to read the name, this is easier and the leading white spaces in the input stream would not be a problem
the user of the code could give a name which contains more than 30 characters, and this input could crash your program, so you should protect your code for this possibility. You have two options:
a. use format '%29s" to read the name
b. change the definition of name to char *name, read it by scanf("%ms", &name);, and call free(name); after you do not need it anymore
Here is an example, in which the name can be very long and can include spaces:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *name;
int age;
printf("Enter name: ");
scanf("%m[^\n]", &name);
printf("Enter age: ");
scanf("%d", &age);
printf("Name: %s\n", name);
printf("Age : %d\n", age);
free(name);
exit(EXIT_SUCCESS);
}
And here is a run of it:
$ ./a.out
Enter name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Enter age: 12
Name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Age : 12
In first code the \n character left behind by the scanf is read by getchar. This makes the condition (ch = getchar())!='\n' in while loop false and the loop body never get executed.
You need to consume that \n character which comes up to the buffer along with the age you entered on pressing Enter key.
Putting the statement
while(getchar()!='\n');
after the scanf will consume all of the newline characters.
Your second code is working fine because %d skips white-space characters unlike %c specifiers.

Resources