My problem looks very simple and im so sorry for asking but what its wrong with this code?! why is just skipping the name part?!
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define nl printf("\n")
struct date{int day,month,year;};
struct student{long int id;char name[30];struct date birthday;};
int main()
{
struct student temp;
nl;nl;printf("ID no:");scanf("%ld",&temp.id);nl;
printf("Student name:");
gets(temp.name);
nl;nl;
printf("Student birthday year:19");scanf("%d",&temp.birthday.year);nl;
printf("Student birthday month");scanf("%d",&temp.birthday.month);nl;
printf("Student birthday day");scanf("%d",&temp.birthday.day);nl;
getch(); //for pause
return 0;
}
Is there anything wrong about gets function?! cause i don't want to use scanf("%s",) because of space thing...
This is because it reads the \n character left behind by scanf. Use
int ch;
while((ch = getchar()) != '\n' && ch != EOF);
to consume \n.
And better not to use gets as it fails in array bound check. Use fgets instead.
As said by haccks, you should not use gets(), but if you really want to use it in your code use gets() before the id no. ie after the struct student temp; line, and if you want to print it then simply puts(temp.name) .
Related
I know there are many questions on the same topic of scanf until EOF is reached, but here's a particular case I haven't seen. Suppose I want to make a C program where the user enters a single character, and the program prints back the character and the number of times the user has entered a character until they press CTRL+D (EOF)
This is what I have:
#include <stdio.h>
int main(){
char thing;
int i=0;
while(scanf("%c", &thing) != EOF){
printf("time:%d, char:%c\n",i,thing);
i++;
}
return 0;
}
However, the output is not as expected. It's the following:
f
time:0, char:f
time:1, char:
p
time:2, char:p
time:3, char:
m
time:4, char:m
time:5, char:
I'm not too sure why i is being incremented again, and why printf gets executed again. Perhaps I'm missing something.
Try
#include <stdio.h>
int main(){
char thing;
int i=0;
while(scanf("%c", &thing) != EOF){
if (thing!='\n') {
printf("time:%d, char:%c\n",i,thing);
i++;
}
}
return 0;
}
#user2965071
char ch;
scanf("%c",&ch);
With such a snippet one reads any ASCII character from the stream including new line, return, tab, or escape. Thus, inside the loop I would test the symbol read with one of the ctype-functions.
Something like this:
#include <stdio.h>
#include <ctype.h>
int main(){
char thing;
int i=0;
while(1 == scanf("%c", &thing)){
if (isalnum(thing)) {
printf("time:%d, char:%c\n",i,thing);
i++;
}
}
return 0;
}
As for me, I think it's not a good idea to check scanf for returning EOF. I would rather check for the number of good read arguments.
#include <stdio.h>
#include <ctype.h> /* for access to the toupper function */
void reverse_name(char *name);
int main(void)
{
char input[100];
printf("Enter a first and last name: ");
gets(input);
reverse_name(input);
return 0;
}
void reverse_name(char *name){
char *first = name;
char *see;
see = name;
while(*see != ' '){
}
while(*see != '\n'){
putchar(*see);
}
printf(", %c",*first);
}
I want this to happen: Enter a first and last name: Lloyd Fosdick
And the output be like this: Fosdick, L.
But after entering a first and last name, Lloyd Fosdick, the program doesn't give any answer and nothing happens? Whats wrong with the code?
You neither increment see nor check for 0 terminator in both of your while loops:
while(*see && *see != ' '){
see++;
}
while(*see && *see != '\n'){
putchar(*see);
see++;
}
gets() has been removed from C11 and you should never use it even if you are following older standards. Use fgets() instead.
This is by no means a complete fix. You'll have to ask yourself:
what if the input contains more than one space between the names?
what if the input contains more than two names?
What if there's no first name or last name?
etc.
You need to think about all these cases and handle them in your code.
You have an infinite loop
while(*see != ' '){}
You need to increment your pointer position.
I think that this is better code
(gets function is deprecated)
You read format code. their is space between firstName and secondName.
No infinite loops not loops at all.
int main(void)
{
char firstName[100];
char secName[100];
printf("Enter a first and last name: ");
scanf("%s %s",firstName,secName);
printf("%s ,%c",secName,firstName[0]);
return 0;
}
I am making a text based game, and i am having a big problem with input. Here is a small example of my problem code.
#include <stdio.h>
#include <stdlib.h>
char c;
int main(int argc, char *argv[]){
system("clear");
while(1){
printf("\nInput a character.\n");
c = getchar();
printf("\nYour input: %c\n", c);
sleep(1);
system("clear");
}
return 0;
}
So, if you compile/run this, and type in 'abc', it will just take each one, and send it through the loop. What I need it to do is only take the very first character that someone types in, no matter how many they do type in.
And, PS: I have tried it this way, and it does the same thing:
#include <stdio.h>
#include <stdlib.h>
char c[2];
int main(int argc, char *argv[]){
system("clear");
while(1){
printf("\nInput a character.\n");
scanf("%1s", c);
printf("\nYour input: %c\n", c[0]);
sleep(1);
system("clear");
}
return 0;
}
EDIT: It also adds a space to what ever you type in, I assume it is a \0, but im not sure. Thanks!
When you use scanf, enter a string and hit the ENTER key, a string and a character are placed in the input buffer, they are namely: the entered string and the newline character. The string or character by character gets consumed by the scanf but the newline remains in the input buffer, unless you consume that too.
getchar(), on the other hand will not wait for ENTER key, it would read character by character, then your logic.
I think you can add 1 more line to read all the characters that come after the first one until there is a newline character (i.e. the user presses Enter):
while (getchar() != '\n');
Adding to your example, it would be like this:
#include <stdio.h>
#include <stdlib.h>
char c;
int main(int argc, char *argv[]){
system("clear");
while(1){
printf("\nInput a character.\n");
c = getchar();
printf("\nYour input: %c\n", c);
sleep(1);
system("clear");
while (getchar() != '\n');
}
return 0;
}
Use getch() which does not wait for a newline.
What i think you look for is something like this code, to save very first character, you can also check if c == '\n' to continue your operation, but i dont know what you want after saving very first character:
int i,c;
char save;
for ( i = 0;(c=getchar())!= EOF ; i++)
{
if ( i == 0)
save = c;
}
You can use fgets(), and extract its first character, like...
char ch[2], c;
fgets(ch, 2, stdin);
c = ch[0];
The problem is when it asks the user to enter the name of the band.The program bypass the first fgets, but executes the printf and not the fgets. I tried to handle this problem with if but again the same problem. Bypass the first fgets. I provide you an image also.
#include <stdio.h>
#include <stdlib.h>
struct cd
{
char band[100];
};
struct cd *music;
int main()
{
int n,i;
printf("Give how many albums you want: ");
scanf("%d",&n);
struct cd *music = malloc(sizeof(struct cd)*n);
for(i=0;i<n;i++)
{
printf("\nEnter Band: ");
fgets(music->band,sizeof(music->band),stdin);
music++;
}
for(i=n-1;i>=0;i--)
music--;
for(i=0;i<n;i++)
{
printf("\nBand: %s",music->band);
music++;
}
printf("\n\n");
return 0;
}
Scanf() treats '\n' as a character and since it is not in the format string, it leaves it there.
try this
char newline;
int n,i;
printf("Give how many albums you want: ");
scanf("%d%c",&n,&newline);
This will remove the '\n' from the stdin.
when you read with scanf() it reads everything leaving the following '\n' from the end
And Now when you try to read with fgets()it reads the'\n' character left by scanf
To solve this you can use fgetc(stdin); after your scanf so that it gets consume.
Ok, thats half of my code, but i have problem and i cant fix it. For example i need to pick choice 2 it is adding something to file, i enter[ name, surname, date, gender ] press enter and program shows like menu again(2.Add to file) but this time automatically picks 2 choice and i need to write data another time and it happens all the time when picking choice 2. Please help me find solution of this problem.
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#define N 15
struct date
{ int da_year;
int da_month;
int da_day;
};
struct studenti
{
int Nr;
char name[25];
char surname[25];
struct date dzd;
char dzimums;
}students[N] ;
int main()
{
sakums:
// FILE *fails_st;
char line[100];
char *ptk; char * end; int i;int sorted;
int g=0,ch,count=0;
int n;
int choice;
FILE *fails_st = fopen("studenti.txt", "r+");
/* errors ja neizdodas atveert failu */
if (fails_st == NULL)
{
printf("Error opening file!\n");
exit(1);
}
printf("\n2.Add to file");
scanf("%d",&choice);
if(choice==2){
/* write in file */
for (n=0; n<1; n++)
{
printf("%d. Ievadiet: vards, uzvards, datums, dzimums >", n+1);
scanf("%s",&students[n].name);
scanf("%s",&students[n].surname);
scanf("%d.%d.%d", &students[n].dzd.da_day, &students[n].dzd.da_month, &students[n].dzd.da_year);
scanf("%c",&students[n].dzimums);
}
fseek(fails_st, 0, SEEK_END);
for (i=0; i<n; i++)
fprintf(fails_st, " %d. %s %s %d.%d.%d %c\n", N+1, students[i].name,
students[i].surname, students[i].dzd.da_day,
students[i].dzd.da_month, students[i].dzd.da_year,
students[i].dzimums);
fclose(fails_st);
goto sakums;
}
getche();
return 0;
}
Your problem is likely that scanf happily does nothing if the format string that is its first parameter doesn't match the available input. That means it won't change the value of choice, so it will still be 2.
The cause of this is probably that what you input doesn't match your format strings. You can detect when this happens by checking the return value of scanf - it will return the number of variables written to, basically. If that is less than the number of format specifiers in your format string, something went wrong.
At that point, you probably want to consume all the available input (maybe something like int c; do { c = getchar(); } while (c != '\n' && c != EOF); for a simple program like yours) and then prompt the user again.
In particular, I believe your scanf("%c", ...) is likely the culprit: %c, unlike most scanf specifiers, will not ignore leading whitespace, but accept any character. So if you typed in "firstname lastname 1980.6.11 f", for example, the previous scanf call will just have consumed "6.11.1980", leaving " f" in the input buffer (note the space). Then the scanf with %c will read the space into the gender field, and leave the "f" in the input buffer. On the next go around, scanf("%d",&choice); will not do anything because "f" is not a valid number, choice will remain 2 and the "f" will get read as the first name on the next student entry, further confusing matters...
The solution is, I believe, to use scanf(" %c", ...); to explicitly consume leading whitespace.