Output is a bunch of zeros besided the printing of the name,code, salary and age, so where is the mistake, it keeps printing in an unformatted way
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
void main(void)
{
//reading formatted text from a file.
int code;
char name[35];
int age;
float salary;
FILE *pointer_;
if ( (pointer_= fopen("Formated.txt","r"))==NULL)
{
printf("File is corrupted.");
}
while((fscanf(pointer_,"%d",&code))!=EOF)
{
fgets(name,35,pointer_);
fscanf(pointer_,"%d", &age);
fscanf(pointer_,"%f", &salary);
printf("%-5d %-35s %-2d %-7.2f",code,name,age,salary);
}
fclose(pointer_);
}
CodePudding user response:
Use constants
NAME_LEN
instead of hard-coding magic values, especially when you repeat that value 3 times.You need to check the return value of all your I/O operations otherwise you may be operating on uninitialized values. Any and all of these could encounter
EOF
of the stream. I used a couple of macros here to make the normal case more readable while still affecting the control in the error case.fgets()
reads a line so the followingfscanf()
will fail if your input fileFormated.txt
[sic] doesn't contain a `\n' after the name field:
1 name
2 3.0
2 name2
3 4.0
As you are reading the file it's not strictly required but it's a good idea
fclose()
the file before exit.It's a good practice to reduce variable scope as much as possible.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK_N(v, n, msg) {\
int tmp = (v);\
if(tmp == EOF) {\
rv = EXIT_SUCCESS;\
break;\
}\
if(tmp != n) {\
printf("%s\n", msg);\
break;\
}\
}
#define CHECK_STR(s, msg) {\
char *tmp = (s);\
if(!tmp) {\
if(feof(pointer_)) {\
rv = EXIT_SUCCESS;\
break;\
}\
printf("%s", msg);\
break;\
}\
}
#define NAME_LEN 35
#define str(s) str2(s)
#define str2(s) #s
int main() {
int rv = EXIT_FAILURE;
FILE *pointer_ = fopen("Formated.txt","r");
if(!pointer_) {
printf("fopen failed");
return rv;
}
for(;;) {
int code;
CHECK_N(fscanf(pointer_,"%d", &code), 1, "code");
char name[NAME_LEN];
CHECK_STR(fgets(name, sizeof(name), pointer_), "name");
name[strcspn(name, "\n")] = '\0';
int age;
float salary;
CHECK_N(fscanf(pointer_,"%d %f", &age, &salary), 2, "age and salary");
printf("%-5d %-" str(NAME_LEN) "s %-2d %-7.2f\n", code, name, age, salary);
}
fclose(pointer_);
return rv;
}
and example output with the above mentioned input. Note that I replaced the \n
in name
with `\0' to format it like this:
1 name 2 3.00
2 name2 3 4.00
CodePudding user response:
Leftover '\n'
fscanf(pointer_,"%d"...
does not consume any '\n'
that may follow the numeric text, thus the following fgets()
reads that line remnant.
while((fscanf(pointer_,"%d",&code))!=EOF)
{
fgets(name,35,pointer_); // May only reads a `\n`.
Lack of result checking
The return values of fgets(name,35,pointer_); fscanf(pointer_,"%d", &age); fscanf(pointer_,"%f", &salary);
are not checked. Unless they are as expected, assuming a good read is folly.
Look for unexpected data after the desired input on each line.
Recommend to read only with fgets()
After successfully reading the lines of data, parse them and check for parsing success.
If still wanting to use fscanf()
Check the return values.