This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
I am programming a simulation, and when the user chooses to create a new tag, the user is supposed to enter a tag ID, the tag's owner, and the object the tag represents. What the program is doing is just skipping over command that scans for the owner, and I'm not quite sure why. My codes are below (the functions are in iotlib.cpp):
iotlib.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 20
struct tagInfo
{
char owner[MAX];
char object[MAX];
int id;
};
struct tre //TRE = Tag Read Event
{
int id;
char node[MAX];
int dx;
};
void initTag(struct tagInfo tag[], int numTags)
{
for(int i=0; i<numTags; i++)
{
printf("Enter the tag ID number: ");
scanf("%i", &tag[i].id);
printf("Enter owner of tag: ");
scanf("%c", &tag[i].owner);
printf("Enter the object the tag is attached to: ");
scanf("%c", &tag[i].object);
}
}
void generateTRE(struct tre event[], int numEvents)
{
for(int i=0; i<numEvents; i++)
{
printf("Enter tag ID: ");
scanf("%i", &event[i].id);
printf("Enter node: ");
scanf("%c", &event[i].node);
printf("Enter distance from node as an integer number of feet: ");
scanf("%c", &event[i].dx);
}
}
void triangulationSimulate(struct tre event1, struct tre event2, int numEvents)
{
if(numEvents>1 && event1.id==event2.id)
{
printf("Node %c", event1.node);
for(int i=0; i<event1.dx; i++)
{
printf(" ");
}
printf("Tag %i", event1.id);
for(int i=0; i<event2.dx; i++)
{
printf(" ");
}
printf("Node %c", event2.node);
}
}
void getTagInfo(struct tagInfo tag)
{
printf("The tag with ID %i represents a/an %c belonging to %c", tag.id, tag.object, tag.owner);
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "iotlib.cpp"
void execute();
int main(void)
{
execute();
return 0;
}
void execute()
{
struct tagInfo tags[5];
struct tre events[5];
int choice, numTags, numEvents;
printf("!Simulation supports a maximum of 5 tags and 5 nodes!\n\n");
printf("Choose a function by entering it's number:\n1. Create tags\n2. Generate Tag Read Events\n3. Triangulate tag\n4. Recall tag metadata\n\n");
scanf("%i", &choice);
if(choice==1)
{
printf("Enter the number of tags to initialize (max of 5): ");
scanf("%i", &numTags);
if(numTags<1 || numTags>5)
{
printf("Invalid datum.\n");
}
else
{
initTag(tags, numTags);
}
}
else if(choice==2)
{
printf("Enter the number of TRE's to be generated (max of 5: ");
scanf("%i", &numEvents);
if(numEvents<1 || numEvents>5)
{
printf("Invalid datum.\n");
}
else
{
generateTRE(events, numEvents);
}
}
else if(choice==3)
{
int eventX, eventY;
printf("Enter two existing TRE numbers to use, separated by a space: ");
scanf("%i %i", &eventX, &eventY);
triangulationSimulate(events[eventX], events[eventY], numEvents);
}
else if(choice==4)
{
int tagNum;
printf("Enter a tag number: ");
scanf("%i", &tagNum);
getTagInfo(tags[tagNum-1]);
}
else
{
printf("Invalid selection.\n");
}
execute();
}
Point 1 [Programmatic error]
The problem here is the usage with %c format specifier. It counts the previously entered \n, stored by pressing the ENTER key after previous input. What you want is
scanf(" %c", &tag[i].owner);
^
|
note the space
to skip any leading whitespace like character (including \n) before the actual input.
Point 2 [Logical Error]
As per your code here, to scan a string input, you need to use %s format specifier.
So, finally, your code should look like
scanf("%s", tag[i].owner); // if tag[i].owner is char array
or
scanf(" %c", &tag[i].owner); // if tag[i].owner is a char, just in case
%c is the specifier for a character, you're trying to input a string, not a character. See scanf documentation. What you want to use is the %s specifier for a string.
Related
I am writing a program where if the user chooses "2" the program will add a new student record and if he chooses "4" then it will compare his surname with all the other surnames, it will find everyone that has the same surname and print their school information. The problems are the following:
When the user selects "2" my program actually shows all the prompts that are needed and you can input all the information however when I try to print it just gives me 0 0 0.000000 .When it should have given me 2(id) B(name) b(surname) 1(semester) 4(grade).
When the user selects "4" it reads the surname but when it goes to compare it with the others to see if it exists or not it just crashes.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student{
int id;
char name[50];
char surname[50];
int semester;
float grade;
}student;
int main()
{
int x,std,i;
x=0;
int car=0;
int flag=1;
struct student *ptr = NULL;
while (x!=8)
{
printf("\n1. Initialize student list\n2. Add a student record\n3. Delete a student record\n4. Display a student record by student surname\n5. Display students passed\n6. Display students failed\n7. Display all student records\n8. Exit");
printf("\nYour choice: ");
scanf("%d",&x);
if (x==1)
{
printf("How many new students? ");
scanf("%d",&std);
ptr = (student*)malloc(std*sizeof(student));
for(i = 0; i < std; i++){
printf("Enter detail of student #%d\n", (i + 1));
ptr[i].id=i+1;
printf("Enter first name: ");
scanf("%s", ptr[i].name);
printf("Enter last name: ");
scanf("%s", ptr[i].surname);
printf("Enter semester: ");
scanf("%d", &ptr[i].semester);
printf("Enter grade: ");
scanf("%f", &ptr[i].grade);
}
}
else if (x==2)
{
ptr=realloc(ptr,100* sizeof(student));
std=std+1;
ptr[std].id=std+1;
printf("Enter first name: ");
scanf("%s", ptr[std].name);
printf("Enter last name: ");
scanf("%s", ptr[std].surname);
printf("Enter semester: ");
scanf("%d", &ptr[std].semester);
printf("Enter grade: ");
scanf("%f", &ptr[std].grade);
flag=0;
}
else if (x==3)
{
/* code */
}
else if (x==4)
{
printf("Give the surname: ");
const char *sur;
scanf("%s", sur);
for (i = 0; i < std; i++)
{
if(strcmp(sur, ptr[i].surname)==0){
printf("%d ", ptr[i].id);
printf("%s ", ptr[i].name);
printf("%s ", ptr[i].surname);
printf("%d ", ptr[i].semester);
printf("%f ", ptr[i].grade);
printf("\n");
car=1;
}
}
if (car=0)
{
printf("That surname does not exist");
}
}
I may have missed a "{" but this is only part of my code
else if (x==7)
{
for(i = 0; i < std; i++){
printf("%d ", ptr[i].id);
printf("%s ", ptr[i].name);
printf("%s ", ptr[i].surname);
printf("%d ", ptr[i].semester);
printf("%f ", ptr[i].grade);
printf("\n");
}
}
}
}
For when the user chooses "2" everything goes well until its time to print so i tried increasing std by 1 two times.One when the program goes to option "2" and another time when it goes back to main. It didnt do anything so i returned it to how it was in the beginning.
For when the user chooses "4" I tried going with strcmp but it would just throw errors because of sur. I had it written as char sur. After I wrote it as const char *sur it stopped throwing errors but it would just crash when it went to compare it with the other.
In this code I am asking for the first and last name for 5 students along with their grades.
I have tried removing the double array from the code and it outputs to console as expected; it is when I am taking input from the user for the character 2-dimensional array and double array in the same for loop that I have the junk output to the first two rows of the character 2-dimensional array. I am unsure why this happens, can someone explain please?
All input is being typed directly into the program.
Output with junk Code below
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size =5;
char name[size*2][20];
double grades[size];
int check=0,i,j;
printf("\nPlease input records of students (enter a new line after each record) as directed.\n\n");
for(i=0;i<size*2;i+=2){
printf("Firstname: ");
scanf("%s",name[i]);
printf("Lastname: ");
scanf("%s",name[i+1]);
printf("Grade: ");
scanf("%lf",&grades[i]);
printf("\n");
}
for(i=0;i<size*2;i+=2){
printf("First Name: ");
printf("%s",name[i]);
printf(" | Last Name: ");
printf("%s",name[i+1]);
printf(" | Grade: %0.1lf\n",grades[i]);
}
}
Output without junk with double array being removed code below
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size =5;
char name[size*2][20];
//double grades[size];
int check=0,i,j;
printf("\nPlease input records of students (enter a new line after each record) as directed.\n\n");
for(i=0;i<size*2;i+=2){
printf("Firstname: ");
scanf("%s",name[i]);
printf("Lastname: ");
scanf("%s",name[i+1]);
//printf("Grade: ");
//scanf("%lf",&grades[i]);
printf("\n");
}
for(i=0;i<size*2;i+=2){
printf("First Name: ");
printf("%s",name[i]);
printf(" | Last Name: ");
printf("%s\n",name[i+1]);
//printf(" | Grade: %0.1lf\n",grades[i]);
}
}
Using the solution the the question: not able to read string after reading double data type outputted the same junk as my original code with junk.
Example with linked solution
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size =5;
char name[size*2][20];
double grades[size];
int check=0,i,j;
printf("\nPlease input records of students (enter a new line after each record) as directed.\n\n");
for(i=0;i<size*2;i+=2){
printf("Firstname: ");
scanf(" %19[^\n]",name[i]);
printf("Lastname: ");
scanf(" %19[^\n]",name[i+1]);
printf("Grade: ");
scanf("%lf",&grades[i]);
printf("\n");
}
for(i=0;i<size*2;i+=2){
printf("First Name: ");
printf("%s",name[i]);
printf(" | Last Name: ");
printf("%s",name[i+1]);
printf(" | Grade: %0.1lf\n",grades[i]);
}
}
Your indexing is off.
Loop like this for(i=0;i<size;i++) and access as [i*2] ... [i*2+1] ... [i].
Once you have gotten through a thousand correctly implemented loops you will know that leaving the safe for(i=0; i<N;i++) is a risk not to be taken.
Alternatively consider using an array of struct, which allows to always use the same index value, instead of having to do the risky index calculation.
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
I wrote this C program to enter names and ages of 3 people. But the output wasn't my expectation. It was able to enter name and age for the first person, but it wasn't able for second and third persons. Please help.
#include <stdio.h>
#include <string.h>
int main()
{
int i, age;
char name[20];
for(i=0; i<3; i++)
{
printf("\nEnter name: ");
gets(name);
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
}
return 0;
}
In short: Your 2nd puts is processing the '\n' from your scanf.
Fix by adding getchar(); after scanf
Explanation:
1st iteration:
printf("\nEnter name: ");
gets(name); // line is read from input
printf("Enter age: ");
scanf(" %d", &age); // a number is read from input, and the newline char ('\n') remains in buffer
puts(name);
printf(" %d", age);
2nd iteration:
printf("\nEnter name: ");
gets(name); // previously buffered newline char is read, thus "skipping" user input
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
Same goes for 3rd iteration, and this is why you lose user input
The best way to store information of more than one person is to use struct, like
struct person {
int age;
char name[20];
};
and make array of struct, like
struct person people[3];
than use loop with accessing people[i].age and people[i].name, e.g.:
#include <stdio.h>
#include <string.h>
struct person {
int age;
char name[20];
};
#define ARR_SIZE 3
int main(int argc, char* argv[])
{
struct person people[ARR_SIZE];
int i;
char *lastpos;
for(i = 0; i < ARR_SIZE; i++)
{
printf("\nEnter name: ");
scanf(" %s", people[i].name);
if ((lastpos=strchr(people[i].name, '\n')) != NULL) *lastpos = '\0'; // remove newline from the end
printf("Enter age: ");
scanf(" %d", &people[i].age);
}
printf("This is the people you entered:\n");
for(i = 0; i < ARR_SIZE; i++)
{
printf("%d : %s : %d\n", i+1, people[i].name, people[i].age);
}
return 0;
}
UPDATE:
As you see I use scanf(" %s", people[i].name); instead of gets(people[i].name); to read name from stdin. Try both option for the following cases:
enter short name (e.g. John) and correct age (e.g. 15)
enter two word name (e.g. John Smith) and correct age (e.g. 17)
enter short name and uncorrect age (e.g. five)
Then read articles about value returned by scanf and cleaning input buffer
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
I am programming a simulation, and when the user chooses to create a new tag, the user is supposed to enter a tag ID, the tag's owner, and the object the tag represents. What the program is doing is just skipping over command that scans for the owner, and I'm not quite sure why. My codes are below (the functions are in iotlib.cpp):
iotlib.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 20
struct tagInfo
{
char owner[MAX];
char object[MAX];
int id;
};
struct tre //TRE = Tag Read Event
{
int id;
char node[MAX];
int dx;
};
void initTag(struct tagInfo tag[], int numTags)
{
for(int i=0; i<numTags; i++)
{
printf("Enter the tag ID number: ");
scanf("%i", &tag[i].id);
printf("Enter owner of tag: ");
scanf("%c", &tag[i].owner);
printf("Enter the object the tag is attached to: ");
scanf("%c", &tag[i].object);
}
}
void generateTRE(struct tre event[], int numEvents)
{
for(int i=0; i<numEvents; i++)
{
printf("Enter tag ID: ");
scanf("%i", &event[i].id);
printf("Enter node: ");
scanf("%c", &event[i].node);
printf("Enter distance from node as an integer number of feet: ");
scanf("%c", &event[i].dx);
}
}
void triangulationSimulate(struct tre event1, struct tre event2, int numEvents)
{
if(numEvents>1 && event1.id==event2.id)
{
printf("Node %c", event1.node);
for(int i=0; i<event1.dx; i++)
{
printf(" ");
}
printf("Tag %i", event1.id);
for(int i=0; i<event2.dx; i++)
{
printf(" ");
}
printf("Node %c", event2.node);
}
}
void getTagInfo(struct tagInfo tag)
{
printf("The tag with ID %i represents a/an %c belonging to %c", tag.id, tag.object, tag.owner);
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "iotlib.cpp"
void execute();
int main(void)
{
execute();
return 0;
}
void execute()
{
struct tagInfo tags[5];
struct tre events[5];
int choice, numTags, numEvents;
printf("!Simulation supports a maximum of 5 tags and 5 nodes!\n\n");
printf("Choose a function by entering it's number:\n1. Create tags\n2. Generate Tag Read Events\n3. Triangulate tag\n4. Recall tag metadata\n\n");
scanf("%i", &choice);
if(choice==1)
{
printf("Enter the number of tags to initialize (max of 5): ");
scanf("%i", &numTags);
if(numTags<1 || numTags>5)
{
printf("Invalid datum.\n");
}
else
{
initTag(tags, numTags);
}
}
else if(choice==2)
{
printf("Enter the number of TRE's to be generated (max of 5: ");
scanf("%i", &numEvents);
if(numEvents<1 || numEvents>5)
{
printf("Invalid datum.\n");
}
else
{
generateTRE(events, numEvents);
}
}
else if(choice==3)
{
int eventX, eventY;
printf("Enter two existing TRE numbers to use, separated by a space: ");
scanf("%i %i", &eventX, &eventY);
triangulationSimulate(events[eventX], events[eventY], numEvents);
}
else if(choice==4)
{
int tagNum;
printf("Enter a tag number: ");
scanf("%i", &tagNum);
getTagInfo(tags[tagNum-1]);
}
else
{
printf("Invalid selection.\n");
}
execute();
}
Point 1 [Programmatic error]
The problem here is the usage with %c format specifier. It counts the previously entered \n, stored by pressing the ENTER key after previous input. What you want is
scanf(" %c", &tag[i].owner);
^
|
note the space
to skip any leading whitespace like character (including \n) before the actual input.
Point 2 [Logical Error]
As per your code here, to scan a string input, you need to use %s format specifier.
So, finally, your code should look like
scanf("%s", tag[i].owner); // if tag[i].owner is char array
or
scanf(" %c", &tag[i].owner); // if tag[i].owner is a char, just in case
%c is the specifier for a character, you're trying to input a string, not a character. See scanf documentation. What you want to use is the %s specifier for a string.
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
I am programming a simulation, and when the user chooses to create a new tag, the user is supposed to enter a tag ID, the tag's owner, and the object the tag represents. What the program is doing is just skipping over command that scans for the owner, and I'm not quite sure why. My codes are below (the functions are in iotlib.cpp):
iotlib.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 20
struct tagInfo
{
char owner[MAX];
char object[MAX];
int id;
};
struct tre //TRE = Tag Read Event
{
int id;
char node[MAX];
int dx;
};
void initTag(struct tagInfo tag[], int numTags)
{
for(int i=0; i<numTags; i++)
{
printf("Enter the tag ID number: ");
scanf("%i", &tag[i].id);
printf("Enter owner of tag: ");
scanf("%c", &tag[i].owner);
printf("Enter the object the tag is attached to: ");
scanf("%c", &tag[i].object);
}
}
void generateTRE(struct tre event[], int numEvents)
{
for(int i=0; i<numEvents; i++)
{
printf("Enter tag ID: ");
scanf("%i", &event[i].id);
printf("Enter node: ");
scanf("%c", &event[i].node);
printf("Enter distance from node as an integer number of feet: ");
scanf("%c", &event[i].dx);
}
}
void triangulationSimulate(struct tre event1, struct tre event2, int numEvents)
{
if(numEvents>1 && event1.id==event2.id)
{
printf("Node %c", event1.node);
for(int i=0; i<event1.dx; i++)
{
printf(" ");
}
printf("Tag %i", event1.id);
for(int i=0; i<event2.dx; i++)
{
printf(" ");
}
printf("Node %c", event2.node);
}
}
void getTagInfo(struct tagInfo tag)
{
printf("The tag with ID %i represents a/an %c belonging to %c", tag.id, tag.object, tag.owner);
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "iotlib.cpp"
void execute();
int main(void)
{
execute();
return 0;
}
void execute()
{
struct tagInfo tags[5];
struct tre events[5];
int choice, numTags, numEvents;
printf("!Simulation supports a maximum of 5 tags and 5 nodes!\n\n");
printf("Choose a function by entering it's number:\n1. Create tags\n2. Generate Tag Read Events\n3. Triangulate tag\n4. Recall tag metadata\n\n");
scanf("%i", &choice);
if(choice==1)
{
printf("Enter the number of tags to initialize (max of 5): ");
scanf("%i", &numTags);
if(numTags<1 || numTags>5)
{
printf("Invalid datum.\n");
}
else
{
initTag(tags, numTags);
}
}
else if(choice==2)
{
printf("Enter the number of TRE's to be generated (max of 5: ");
scanf("%i", &numEvents);
if(numEvents<1 || numEvents>5)
{
printf("Invalid datum.\n");
}
else
{
generateTRE(events, numEvents);
}
}
else if(choice==3)
{
int eventX, eventY;
printf("Enter two existing TRE numbers to use, separated by a space: ");
scanf("%i %i", &eventX, &eventY);
triangulationSimulate(events[eventX], events[eventY], numEvents);
}
else if(choice==4)
{
int tagNum;
printf("Enter a tag number: ");
scanf("%i", &tagNum);
getTagInfo(tags[tagNum-1]);
}
else
{
printf("Invalid selection.\n");
}
execute();
}
Point 1 [Programmatic error]
The problem here is the usage with %c format specifier. It counts the previously entered \n, stored by pressing the ENTER key after previous input. What you want is
scanf(" %c", &tag[i].owner);
^
|
note the space
to skip any leading whitespace like character (including \n) before the actual input.
Point 2 [Logical Error]
As per your code here, to scan a string input, you need to use %s format specifier.
So, finally, your code should look like
scanf("%s", tag[i].owner); // if tag[i].owner is char array
or
scanf(" %c", &tag[i].owner); // if tag[i].owner is a char, just in case
%c is the specifier for a character, you're trying to input a string, not a character. See scanf documentation. What you want to use is the %s specifier for a string.