Ok so i have a text file database.txt.
Each line is a user with the format below
"John Smith"| 4| 80.00| "123 Lollipop Lane"| "New Jersey"| "08080"
When I try do the following:
database = fopen(fileName,"r");
while(fscanf(database,"%[^\n]", buffer) != EOF) {
printf("ATTEMPT TO: Insert user %s\n\n", buffer);
if (insert_Customer(clients, create_Customer(buffer)) < 0) {
printf("\nERROR: Failed to insert and create customer %s\n", buffer);
}
else printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
}
It runs fine for the first line, sending in the ENTIRE line to the create_Customer(char * buffer) function. For some reason I do not understand, after this first line it continually tries to send "John Smith" instead of moving on to the next line. I believe my format is incorrect but I can't figure out how to accomplish what I am trying to accomplish which is read this file line by line and pass each line into the create_Customer function.
I think you need a closing \n
in your pattern. I saw the a bunch of scrolling text with the same first line with %[^\n]
, but with %[^\n]\n
I saw the expected output.
However, if the line in the file exceeds that of the buffer, you may run into a problem where your buffer doesn't have enough space. The results
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE * database;
char buffer[30];
database = fopen("test.txt", "r");
if (NULL == database)
{
perror("opening database");
return (-1);
}
while (EOF != fscanf(database, "%[^\n]\n", buffer))
{
printf("> %s\n", buffer);
}
fclose(database);
return (0);
}
> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
*** stack smashing detected ***: ./fscanf terminated
Segmentation fault (core dumped)
Let's fix the code so that we don't overrun our buffer. We do this by changing %[^\n]\n
to %30[^\n]\n
. This tells fscanf that it can only use upto the size of the buffer -- 30.
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE * database;
char buffer[30];
database = fopen("test.txt", "r");
if (NULL == database)
{
perror("opening database");
return (-1);
}
while (EOF != fscanf(database, "%30[^\n]\n", buffer))
{
printf("> %s\n", buffer);
}
fclose(database);
return (0);
}
It looks like it worked!
> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdf
> jklzxcv;jkl;eqwrtjklkzlcxvjkle
> qrt41234
This is what the test file looks like that I was using.
12343456567856789
zbasdflkjasdfkjklsdafjklas
zxcvjkleryjkldhfg
1234567890123456789012341234
12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
Any reason you are using fscanf
and not fgets
?
One thing to note if you use fgets
, you may want to strip the \n
character because it will be included as part of the string.
From cplusplus.com fgets
:
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
Example:
/* fgets example */
#include <stdio.h>
int main()
{
FILE * database;
int res;
char buffer [100];
database = fopen(fileName,"r");
if (NULL == database) {
perror("opening database file");
return (-1);
}
/* while not end-of-file */
while (!feof(database)) {
/* we expect buffer pointer back if all is well, get out if we don't get it */
if (buffer != fgets(buffer, 100, database))
break;
/* strip /n */
int len = strlen(buffer);
if (buffer[len - 1] == '\n')
buffer[len - 1] = 0;
printf("ATTEMPT TO: Insert user %s\n\n", buffer);
if (insert_Customer(clients, create_Customer(buffer)) < 0)
printf("\nERROR: Failed to insert and create customer %s\n", buffer);
else
printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
}
/* a little clean-up */
fclose(database);
return (0);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With