Reputation: 1
I have to program a new file in which I have to have multiple student info (like: Student_name, student_Surname, school_subject
and number of student) in one line and I have to type in new students until I input END.
I have to use printf and scanf. Name, surname and subject can be multiple words When I try to use scanf("[^\n]*c", name)
, I can only enter info for one student and loop just ignores rest and for other students I can just type in student number which is integer.
What is wrong with my code?
int main() {
FILE *outputfile = NULL;
struct imenik {
char prezime[17 + 1];
char ime[13 + 1];
char predmet[20 + 1];
int bodovi;
} ucenik;
outputfile = fopen("imenik.txt", "w");
printf("Ucitaj ime ucenika: ");
scanf("%[^\n]%*c", ucenik.ime);
printf("Ucitaj prezime ucenika: ");
scanf("%[^\n]%*c", ucenik.prezime);
printf("Ucitaj predmet: ");
scanf("%[^\n]%*c", ucenik.predmet);
printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);
fprintf(outputfile, "%s | %s | %s | %d\n", ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
fclose(outputfile);
}
Upvotes: 0
Views: 797
Reputation: 492
I suggest you an implementation like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S_SIZE 32
#define T_SIZE 128
int main(void) {
FILE *outputfile = NULL;
struct imenik {
char prezime[S_SIZE];
char ime[S_SIZE];
char predmet[S_SIZE];
int bodovi;
} ucenik;
outputfile = fopen("imenik.txt", "a");
if (outputfile == NULL) {
perror("Fopen");
exit(EXIT_FAILURE);
}
char tmp[T_SIZE];
while (1) {
printf("Enter info separated with spaces: ");
fgets(tmp, T_SIZE, stdin);
if (strcmp(tmp, "END\n") == 0) {
break;
}
sscanf(tmp, "%s %s %s %d", ucenik.ime, ucenik.prezime, ucenik.predmet, &ucenik.bodovi);
fprintf(outputfile, "%s | %s | %s | %d\n", ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
}
fclose(outputfile);
return 0;
}
Upvotes: 1
Reputation: 21318
Your line:
scanf("%d", &ucenik.bodovi);
leaves a newline in the input stream. This gets picked up by the next call to scanf()
, which immediately exits, also leaving the newline behind, and so on. Do not try adding a trailing whitespace character to the format string, as some suggest: "%d "
. This will consume the newline at the end of your input, and wait for more input, until a non-whitespace character or EOF
is encountered.
The easiest solution is to do what you have already been doing to discard newlines:
scanf("%d%*c", &ucenik.bodovi);
Note that you should specify a maximum width in format strings when using scanf()
to read into a string to avoid buffer overflow:
scanf("%13[^\n]%*c", ucenik.ime);
Also, you should be checking outputfile
to be sure that the file has opened successfully.
One way to implement the loop would be to place the first call to scanf()
outside of the loop, then use strcmp()
in the while
statement to check for "END"
. At the end of the loop, duplicate the first call to scanf()
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *inputfile = NULL;
FILE *outputfile = NULL;
struct imenik {
char prezime[17 + 1];
char ime[13 + 1];
char predmet[20 + 1];
int bodovi;
} ucenik;
outputfile = fopen("imenik.txt", "w");
/* Did file open successfully? */
if (outputfile == NULL) {
perror("Unable to open file:");
exit(EXIT_FAILURE);
}
/* Specify maximum widths in calls to scanf() */
printf("Ucitaj ime ucenika: ");
scanf("%13[^\n]%*c", ucenik.ime);
while (strcmp(ucenik.ime, "END") != 0) {
printf("Ucitaj prezime ucenika: ");
scanf("%17[^\n]%*c", ucenik.prezime);
printf("Ucitaj predmet: ");
scanf("%20[^\n]%*c", ucenik.predmet);
printf("\nUcitaj broj bodova (0-50): ");
scanf("%d%*c", &ucenik.bodovi);
fprintf(outputfile, "%s | %s | %s | %d\n",
ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
printf("Ucitaj ime ucenika: ");
scanf("%13[^\n]%*c", ucenik.ime);
}
fclose(outputfile);
return 0;
}
Upvotes: 0
Reputation: 780724
The problem is here:
scanf("%d", &ucenik.bodovi);
This reads the number, but it doesn't read the newline after it. So when the loop repeats, It reads that newline as an empty line of input for the next student name.
You can change it to:
scanf("%d ", &ucenik.bodovi);
The space tells it to skip over any whitespace after the number.
But actually, it's better to put the space at the beginning of each scanf
, rather than ignoring the newline at the end. See http://stackoverflow.com/questions/19499060/what-is-difference-between-scanfd-and-scanfd for the explanation. So change it to:
printf("Ucitaj ime ucenika: ");
scanf(" %[^\n]", ucenik.ime);
printf("Ucitaj prezime ucenika: ");
scanf(" %[^\n]", ucenik.prezime);
printf("Ucitaj predmet: ");
scanf(" %[^\n]", ucenik.predmet);
printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);
Upvotes: 1