what is mistake ? i cant find any mistake in my code but it does not take input properly and it also displays some garbage values.
Thanks:
int main()
{
struct book
{
char name;
int price;
int pages;
};
struct book b[5];
int i;
for (i = 0; i < 5; i++)
{
printf("enter name price pages\n");
scanf("%c", &b[i].name);
scanf("%d", &b[i].price);
scanf("%d", &b[i].pages);
}
for (i = 0; i < 5; i++)
printf("%c %d %d\n", b[i].name, b[i].price, b[i].pages);
return 0;
}
Most books have a name that is longer than a single letter.
You need to adjust the structure accordingly:
enum { MAX_BOOKNAMELEN = 32 }; // Probably too short
struct book
{
char name[MAX_BOOKNAMELEN];
int price;
int pages;
};
You also need to adjust the input:
if (scanf("%31[^\n]", b[i].name) != 1)
...report error; do not use this book entry...
The '31' is magicked out of thin air; it is one less than MAX_BOOKNAMELEN. Note that book titles frequently contain spaces; thus %s which skips leading spaces and stops at the first space after one or more non-space characters is not appropriate for reading titles. One way to create the format string is via sprintf() — this will adapt if MAX_BOOKNAMELEN changes size:
char name_fmt[16];
snprintf(name_fmt, sizeof(name_fmt), "%%%d[^\n]", MAX_BOOKNAMELEN-1);
if (scanf(name_fmt, b[i].name) != 1)
...error...
A more thorough revision would probably use fgets() and sscanf() or other tools instead of calling scanf() directly.
this line
scanf("%c",&b[i].name);
should be
scanf(" %c",&b[i].name);
See How to do scanf for single char in C
Since I've been informed to specifically answer the question (sorry, Im new here), the problem lies in the %c picking up whitespace and/or newline characters. The easiest way to prevent this is put a " " in front of it.
#include <stdio.h>
int main()
{
struct book
{
char name;
int price;
int pages;
};
struct book b[5];
int i;
for(i=0;i<5;i++)
{
printf("enter name price pages\n");
scanf(" %c %d %d",&b[i].name, &b[i].price, &b[i].pages); //here
//%c was grabbing whitespace and/or newline causing the problem.
}
for(i=0;i<5;i++)
printf("Name: %c Price: %d Pages: %d\n",b[i].name,b[i].price,b[i].pages);
return 0;
}
Output:
enter name price pages
a 1 2
enter name price pages
b 3 4
enter name price pages
c 5 6
enter name price pages
d 7 8
enter name price pages
e 9 10
Name: a Price: 1 Pages: 2
Name: b Price: 3 Pages: 4
Name: c Price: 5 Pages: 6
Name: d Price: 7 Pages: 8
Name: e Price: 9 Pages: 10
What happens is that the last scanf("%d"), reads the number and let a '\n' at the buffer, so next time you call scanf("%c"), it will read the '\n' in the buffer, and not the new character.
One possible solution to use scanf, is to tell scanf to read everything in the line, and discard it:
scanf("%c%*[^\n]\n", &b[i].name);
scanf("%d%*[^\n]\n", &b[i].price);
scanf("%d%*[^\n]\n", &b[i].pages);
This way, scanf will block until you press enter, and will read the '\n'.
try it like this :
scanf(" %c %d %d",&b[i].name, &b[i].price, &b[i].pages);
while(getchar()!='\n');
Related
This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 2 years ago.
Hello senior programmers! I am new in programming. I am having trouble making my program run efficiently. My code works perfectly fine when I do not give white space. But when I give white space while writing the name or route it doesn't work.
Example: Driver's Name: ALI ( work perfectly )
Example: Driver's Name: ALI ALI ( not working )
I want to write all the char with white space. I have already tried every possible way. I have commanded all the ways which I have tried. I am a beginner. It is my college assignment. Kindly, please help me, How can I fix this?
/*
You manage a travel agency and you want your n drivers to input their following details:
1. Name
2. Driving License No
3. Route
4. Kms
Your program should be able to take n as input(or you can take n=3 for simplicity) and your drivers will start inputting their details one by one.
Your program should print details of the drivers in a beautiful fashion.
User structures.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Max_Size 1000
#define max 1000
struct Drivers
{
char Name[150];
char Driving_License_No[150];
char Route[150];
char Kms[50];
int positionNo;
} drivers[Max_Size];
int main()
{
int totalDrivers;
char name[200];
printf("Enter the total numbers of drivers\n");
scanf("%d", &totalDrivers);
for (int i = 0; i < totalDrivers; i++)
{
drivers[i].positionNo=i+1;
printf("\nFor Driver Id no. %d,\n", drivers[i].positionNo);
printf("Enter the full name: ");
scanf("%s", &drivers[i].Name);
// scanf("%[^\n]",drivers->Name);
// scanf("%[^\n]s",drivers->Name);
// fgets(drivers.Name, 150, stdin);
// gets(Name);
// gets(driver.Name);
printf("Enter the Driving License no : ");
scanf("%s", &drivers[i].Driving_License_No);
printf("Enter the Driving Route : ");
scanf("%s", &drivers[i].Route);
printf("Enter the Driving KM's : ");
scanf("%s", &drivers[i].Kms);
}
printf("The Information of all drivers are given below\n");
for (int i = 1; i < totalDrivers; i++)
{
printf("\nDriver Id no.: %d\n", i + 1);
printf("Driver's Name: ");
puts(drivers[i].Name);
printf("Driving License no: %s", drivers[i].Driving_License_No);
printf("\n");
printf("Driving Route: %s", drivers[i].Route);
printf("\n");
printf("Driving KM's: %s", drivers[i].Kms);
printf("\n");
}
return 0;
}
There are multiple issues:
parsing a string with embedded white space can be done with %[^\n] in scanf().
you should tell printf the maximum number of characters to store into the destination arrays to avoid potential undefined behavior on invalid input.
&drivers[i].Name is not a char *, you should pass drivers[i].Name.
when printing the details, you start at 1 instead of 0.
to input multiple strings with embedded spaces, which is likely required here, you should use " %[^\n]" with an initial space to skip the pending newline and any initial spaces.
Here is a modified version:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Max_Size 1000
#define max 1000
struct Drivers {
char Name[150];
char Driving_License_No[150];
char Route[150];
char Kms[50];
int positionNo;
} drivers[Max_Size];
int main() {
int totalDrivers;
char name[200];
printf("Enter the total numbers of drivers\n");
if (scanf("%d", &totalDrivers) != 1)
return 1;
if (totalDrivers > Max_Size) // avoid overflowing the drivers array;
totalDrivers = Max_Size;
for (int i = 0; i < totalDrivers; i++) {
drivers[i].positionNo = i + 1;
printf("\nFor Driver Id no. %d,\n", drivers[i].positionNo);
printf("Enter the full name: ");
scanf(" %149[^\n]", drivers[i].Name);
printf("Enter the Driving License no: ");
scanf(" %149s", drivers[i].Driving_License_No);
printf("Enter the Driving Route: ");
scanf(" %149s", drivers[i].Route);
printf("Enter the Driving KM's: ");
scanf(" %49s", drivers[i].Kms);
}
printf("The Information of all drivers are given below\n");
for (int i = 0; i < totalDrivers; i++) {
printf("\n");
printf("Driver Id no.: %d\n", i + 1);
printf("Driver's Name: %s\n", drivers[i].Name);
printf("Driving License no: %s\n", drivers[i].Driving_License_No);
printf("Driving Route: %s\n", drivers[i].Route);
printf("Driving KM's: %s\n", drivers[i].Kms);
}
return 0;
}
See instead of using %s as format specifier you should use %[^\n] as the format specifier while taking input in scanf to take the input with white spaces.
printf("Enter the full name: ");
scanf("%[^\n]", drivers[i].Name);
In case of any query please feel free to ask.
um.. i have a question when i study standard input / output file system in C lang.
what's difference '$%f' and '%f' ??
int main()
{
int ctr;
struct bookInfo books[3];
for (ctr = 0; ctr < 3; ctr++)
{
printf(" what is book #%d? \n", (ctr + 1));
gets(books[ctr].title);
puts("who is author ? ");
gets(books[ctr].author);
puts("how much price this book?");
scanf(" $%f", &books[ctr].price);
}
return 0;
}
%f is just normal float, and the $ in the last scanf, is just a symbol: dollar symbol. There is actually no character such as $%f. Since the last scanf requires price of the book, you should put $ before it (e.g. $20 equals 20 dollars).
scanf(" $%f", &books[ctr].price); scans from stdin
0 or more white-spaces
a single '$'. If not, scanning stops anscanf() returns 0 (or maybe EOF).
If input text then matches a floating point number, it is saved in books[ctr].price.
It takes in a word and a number, I can't seem to understand why the number variable won't receive the input, help please.
#include <stdio.h>
int main(void) {
char userWord[20];
int userNum;
scanf("%s", userWord);
printf("%s_", userWord);
scanf("%s", userNum);
printf("%d\n", userNum);
return 0;
}
Should be:
Input: Stop 7
Output: Stop_7
What I get:
Input: Stop 7
Output: Stop_0
Change
scanf("%s", userNum);
to
scanf("%d", &userNum);
You used format %s for reading in an integral value; it should have been %d.
Once having fixed this (i.e. by writing scanf("%d", &userNum);, note that your code will read in a string and a number even if the string and the number were not in the same line (cf., for example, cppreferene/scanf concerning format %s and treatment of white spaces). Further, you will run into undefined behaviour if a user enters a string with more than 19 characters (without any white space in between), because you then exceed your userWord-array.
To overcome both, you could read in a line with fgets, then use sscanf to parse the line. Note that you can parse the line in one command; the result of scanf is then the number of successfully read items. Further, note the %19s, which limits the input to 19 characters (+ the final string termination character '\0'):
int main() {
char line[100];
if (fgets(line,100,stdin)) {
char userWord[20];
int userNum;
if (sscanf(line, "%19s %d", userWord, &userNum) != 2) {
printf("invalid input.\n");
} else {
printf("word:'%s'; number: %d", userWord, userNum);
}
}
}
I have written the program
#include<stdio.h>
struct student
{
char name[22];
char rollno[10];
unsigned long long int phno;
};
int main()
{
int i,j;
char c[1];
struct student cse[10],*p;
p=cse;
for(i=0;i<3;i++)
{
printf("enter student name\n");
gets(cse[i].name);
printf("enter student roll number \n");
gets(cse[i].rollno);
printf("enter student phone number \n");
scanf("%llu",&cse[i].phno);
gets(c); //to catch the '\n' left unprocessed by scanf
}
for(i=0;i<3;i++);
printf("the following is the information about CSE B student\n");
printf("%-6s%-24s%-14s%-14s \n","S.no","student Name","Roll no","phone no.");
for(i=0;i<3;i++)
{
printf("%-6d%-24s%-20s%-14llu \n",i+1,(*p).name,(*p).rollno,(*p).phno);
++p;
}
return 0;
}
the output is
the following is the information about CSE B student
S.no student Name Roll no phone no.
1 kapil 1234567890��I 1234567890
2 kumar 9876543210��L 9876543210
3 sharma 5123467890��a1 5123467980
there are some unwanted and ununderstandable characters in the Roll no coloumns ,what is the cause of printing of those invalid characters
~
The array rollno has storage only for 10 chars but you are inputting 10 or more chars. If your roll numbers are 10 digits, you need at least 11 chars to print it as string, one extra for the terminating null-byte. This is technically undefined behaviour, making your program invalid.
Note that gets() has been deprecated since C11 and you should really be using fgets() instead.
I have a problem writing code which does the following: declare a struct{char c; int x; } array and load it with scanf via a loop. After it's loaded, a call to function f will be made which will replace every occurrence of digits in the struct's component c with 0, and will return the sum of the digits replaced by zero.
Code and output are below and I have problem that the loop in the function f seems to iterate one time, and it gives out some really weird values.
This is an exam question so I have to use printf, scanf etc. Also I have that exam in an hour so any quick help is appreciated :)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 2
struct par {
char c;
int x;
};
int f(struct par *niz) {
int i;
int n=0;
for(i=0; i<MAX; i++) {
if(isdigit(niz[i].c)) {
niz[i].c = niz[i].c-'0';
printf("niz[i].c = %d\n i = %d", niz[i].c, i);
n=n+niz[i].c;
niz[i].c='0';
}
}
return n;
}
void main() {
int n;
int i;
struct par niz[MAX];
printf("enter\n");
for(i=0; i<MAX; i++) {
scanf("%c", &niz[i].c);
scanf("%d", &niz[i].x);
}
n=f(niz);
for(int i=0; i<MAX; i++) {
printf("%d\n", niz[i].c);
printf("%d\n", niz[i].x);
}
printf("n = %d\n", n);
}
OUTPUT:
enter
2
2
2
niz[i].c = 2
i = 048
2
10
2
n = 2
When you press enter after the first input, the newline is not scanned by scanf and is left in the input buffer. When you then try to read the number scanf sees the newline and not a number so doesn't scan anything.
The simple solution to that is to add a leading space in front of the formats:
scanf(" %c", &niz[i].c);
scanf(" %d", &niz[i].x);
/* ^ */
This tells scanf to skip whitespace.
Use
niz[i].c = getchar();
instead of
scanf("%c", &niz[i].c);
or, you can use other better methods for getting char input discussed at SO,
Now,
You see second time you provided input only once, that is because the Enter you pressed after giving 2 as input to first char remained in input buffer, and was read on second iteration.
You are getting 10 as output, because, it is ASCII for \r, the Enter. It is not a digit, so not replaced to be '0'.
I am looking at your code (i am not using console for a decade, but ) here are some insights:
try to rename MAX with something else
do not know your IDE but sometimes MAX is reserved
and using it as macro can cause problems on some compilers
change scanf("%c", &niz[i].c) to scanf("%c", &(niz[i].c))
just to be shore that correct adsress is send to scanf
change scanf("%d", &niz[i].x) to scanf("%i", &(niz[i].x))
change "%d" to the correct value (this is main your problem)
"%c" for char
"%i" for int
Try to trace line by line and watch for improper variables change if above points does not help
weird values?
because you forgot "\n" after the line, so next print is behind the line "i = %d".
And, check return value of every function except ones that return void.