I have these in my file:
JOS BUTTLER
JASON ROY
DAWID MALAN
JONNY BAISTROW
BEN STOKES
in different lines. And I want them to extract in my program to print them on the exact way they are in file. My imaginary output screen is:
JOS BUTTLER
JASON ROY
DAWID MALAN
JONNY BAISTROW
BEN STOKES
How would I do it using fscanf()
and printf()
. Moreover suggest me the way to change the delimiters of fscanf()
to \n
I have tried something like this:
char n[5][30];
printf("Name of 5 cricketers read from the file:\n");
for(i=0;i<5;i )
{
fscanf(fp,"%[^\n]s",&n[i]);
printf("%s ",n[i]);
}
fclose(fp);
}
But it works only for the first string and other string could not be displayed. There were garbage values.
CodePudding user response:
Be protected from buffer overflows limiting the length of the input, use ")[^\n]"
instead of "%[^\n]s"
(you don't need the s
specifier)
Consume the trailing new line (your wildcard ^\n
reads until a new line is found) using %*c
, *
means that a char
will be read but won't be assigned:
fscanf(fp, ")[^\n]%*c", n[i]);
or better yet (as pointed out by @WeatherVane), add a space before %
, this will consume any blank space including tabs, spaces and new lines that may be left in the buffer from the previous read:
fscanf(fp, " )[^\n]", n[i]);
Notice that you don't need an ampersand in &n[i]
, fscanf
wants a pointer but n[i]
is already (decays into) a pointer when passed as an argument.
Finally, as pointed out by @paddy, fgets
does all that for you and is a safer function, always prefer fgets
.
CodePudding user response:
How to get string terminated with new line in file handling using fscanf
Use fgets()
to read a line of input into a string. It also reads and saves the line's '\n'
.
Buffer size 30 may be too small, consider 60.
To detect if the line is too long and lop off the '\n'
, read in at least 2 characters.
// char n[5][30];
#define NAME_N 5
#define NAME_SIZE 30
char n[NAME_N][NAME_SIZE]
char buf[NAME_SIZE 2]
while (i < NAME_N && fgets(buf, sizeof buf, fp) != NULL) {
size_t len = strlen(buf);
// Lop off potential trailing '\n'
if (len > 0 && buf[len - 1] == '\n') {
buf[--len] = '\0';
}
// Handle unusual name length
if (len >= NAME_SIZE || len == 0) {
fprintf(stderr, "Unacceptable name <%s>.\n", buf);
exit(EXIT_FAILURE);
}
// Success
strcpy(n[i], buf);
printf("%s\n", n[i]);
i ;
}