Reputation: 1561
I have a C / fscanf() question. FULL DISCLAIMER: I am CS student, working on an assignment. My code works, but the graders will compile our submissions with using the GCC "all errors and warnings" option:
gcc -Wall yourCodeHere.c
My code works, but I'm getting a warning which bugs me... and could lead to problems with the grader. My code is simple, it scans each line of a file into a string, then tosses that string to a function:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void printString(char* string){
printf("file line is: \"%s\"\n", string);
}
int main(int argc, char *argv[]){
char *myFile = argv[1];
FILE *targetFile;
targetFile = fopen(myFile, "r");
if (targetFile == NULL) {
// some problem with the input file
return -1;
} else {
char* string;
while (fscanf(targetFile, "%s\n", string) != EOF){
printString(string);
}
}
fclose(targetFile);
return 1;
}
The warning is:
$ gcc -Wall myCode.c
myCode.c: In function ‘main’:
myCode.c:21:4: warning: ‘string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
printString(string);
^
$
I get what the compiler is trying to say: "What if 'string' is not holding valid data?" Its a valid point; I'm kinda assuming that every line of the input file will produce a working string.
So: how to check this and get rid of that annoying warning? I note that fscanf() returns the number of items successfully scanned, so I tried this:
int num = 1; // initialize to something >0
while (num = (fscanf(targetFile, "%s\n", string) != EOF) > 0){
printString(string);
}
But that produced two warnings:
$ gcc -Wall myCode.c
myCode.c: In function ‘main’:
myCode.c:21:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
while (num = (fscanf(targetFile, "%s\n", string) != EOF) > 0){
^
myCode.c:22:4: warning: ‘string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
printString(string);
^
$
Plus, I worry that this would cause the program to stop reading the file too early if fscanf() returned 0 for some valid reason.
So... Not certain how to get around this. In Java, I'd simply say "if(string != NULL) ..." and move on. But you can't do that in C. There must be some quick way of checking that fscanf() grabs a valid string before I call the external function.
Anyone know a fix?
Thanks! -Pete
PS - Apologies if this is more a GCC question than a C question. :(
Upvotes: 1
Views: 799
Reputation: 153348
How to check that fscanf() returns valid string in C?
1) Insure space is provided to save the data 2) Limit the amount of data read 3) test the result of the input funciton.
// #1 Provide space `char* string` is simple a pointer with an uninitialized value
// char* string;
// Select a reasonable upper bound: recommend 2x expected max size
char string[100];
// #2 Limit width to reading up to 99 characters,
// 1 less than buffer size as `fscanf()` will append a null character
// while (fscanf(targetFile, "%s\n", string) != EOF){
// while (fscanf(targetFile, "%99s\n", string) != EOF){
// #3 Check against the desired success value,
// do not check against one of the undesired values
while (fscanf(targetFile, "%99s\n", string) == 1) {
Upvotes: 2
Reputation: 12382
string
in your code is a pointer rather than an array. There is no memory allocated for fscanf
to copy the characters into. Changing it to a character array will work as would string = malloc(X);
where X is the number of bytes you want to allocate. Remember that you'll need an extra byte for the '\0' termination of the string. Also remember that you have no idea how big the line of test could be and fscanf
will just copy bytes without caring about length, which brings up another issue -- how is fscanf
supposed to know to copy an entire line rather than just a word or a character? You should look into that!
Upvotes: 2