Here are some indications to fix your program:
to read the name before the :
, you can use %[^:]
to avoid a potential buffer overflow, you should specify the maximum number of characters to store into the destination array:
char name[30];
scanf("%29[^:]", name);
to skip the pending newline and potential initial whitespace, add a space at the start of the format string:
char name[30];
scanf(" %29[^:]", name);
to consume the :
, just add a :
after the conversion format.
to parse the number, use the %lf
conversion if balance
has type double
, but pass the address of the variable with the &
:
char name[30];
double balance;
scanf(" %29[^:]: %lf", name, &balance);
why not use &
for name
you might ask... because name
is an array: passing an array as an argument to a function implicitly passes a pointer to its first element. You could do this explicitly as &name[0]
but it is simpler and idiomatic to just pass name
.
you should check that the conversions succeeded: scanf()
returns the number of successful conversions, hence it will return 2
if the input was parsed correctly.
your output shows Miguel:: 0.0000
because the :
was read as part of the name with %s
and the balance was printed with a %.4f
format. The first problem is solved thanks to the %29[^:]
conversion, for the second you should use %.2f
to output 2 decimals.
To make it easier to detect the end of file and recover from invalid input, it is recommended to read one line at a time with fgets()
and use sscanf()
to attempt to convert the contents of the line.
Here is a function to parse the file:
#include <stdio.h>
int read_file(FILE *fp) {
char line[200];
char name[30];
double balance;
int count = 0;
while (fgets(line, sizeof line, fp)) {
if (sscanf(line, " %29[^:]: %lf", name, &balance) == 2) {
count++;
printf("%s: %.2f\n", name, balance);
} else {
printf("invalid input: %s\n", line);
}
}
return count; // return the number of lines converted
}
Note that this method will accept and ignore extra contents after the balance on the line. To detect and report this problem, you can use the %n
conversion to retrieve the number of characters read and report the problem if the line has extra non whitespace contents:
#include <stdio.h>
int read_file(FILE *fp) {
char line[200];
int count = 0;
while (fgets(line, sizeof line, fp)) {
char name[30];
double balance;
int len = 0;
if (sscanf(line, " %29[^:]: %lf %n", name, &balance, &len) == 2) {
count++;
printf("%s: %.2f\n", name, balance);
if (line[len] != '\0') {
printf("extra characters: %s\n", line + len);
}
} else {
printf("invalid input: %s\n", line);
}
}
return count; // return the number of lines converted
}