I need to read the following from a data file:
Sabre Corporation 15790 West Henness Lane New Corio, New Mexico 65790
My variables are char companyName[20+1], char companyAddress[30+1], char companyCity[15+1], char companyState[15+1], int companyZip;
I read the first line for companyName just fine using %[^\n], but trying to read the second line the same, the variable stays empty.
void getCompanyData(FILE *CompanyFile, char *companyName, char *companyAddress, char *companyCity, char *companyState, int *companyZip)
{
fscanf(CompanyFile,"%[^\n]%[^\n]%s%s%d", companyName, companyAddress, companyCity, companyState, companyZip);
}
When I run this code and print out the variables, companyName looks fine, "Saber Corporation", but companyAddress isn't displayed as anything.
If I switch the second input to simply %s it reads the numbers of the address just fine.
Is there a way to read the whole line as one variable like the first line, instead of concatenating a number of other variables into a larger one?
A Little translation from C.
"%[^\n]%[^\n]%s%s%d"
%[^\n] // reads everything up to the new line
// But does not read the new line character.
// So there is still a new line character on the stream.
%[^\n]%[^\n] // So the first one reads up to the new line.
// The second one will immediately fail as there is a new line
// still on the stream and thus not read anything.
So:
int count = scanf(CompanyFile,"%[^\n]%[^\n]%s%s%d", /*Variables*/ );
printf("Count = %d\n", count);
Will print 1 as only one variable has been filled.
I know it is tempting to use the following to read a line.
fscanf("%[^\n]\n", /* Variables*/ );
But that is a bad idea as it is hard to spot empty lines. An empty line will not read anything into the variable and thus fail before reading the new line so it effectively will not read the empty line. So best to break this into multiple statements.
int count;
do {
count = fscanf("%[^\n]", /* Variables*/ );
fscanf("\n");
} while (count == 0);
// successfully read the company name and moved on to next line
// while skipping completely empty lines.
Now that seems logical extension of the above.
But that would not be the best way to do it. If you assume that a line may start with the '\n' from the previous line (and you want to ignore any leading white space on the data line) then you can use a space before.
int count = fscanf(" %[^\n]", /* Variables*/ );
// ^ The leading space will drop all white space characters.
// this includes new lines so if you expect the last read may
// have left the new line on the stream this will drop it.
Another thing to note is that you should always check the return value of a fscanf() to make sure the number of variables you expect to have scanned was actually scanned.
Is there a way to read the whole line as one variable like the first line, instead of concatenating a number of other variables into a larger one?
When the goal is to read a line (all characters up to and including a '\n'), use fgets().
buffer[256];
if (fgets(buffer, sizeof buffer, CompanyFile) {
// success!
}
After reading the line into a string, parse it.
"Sabre Corporation 15790 West Henness Lane New Corio, New Mexico 65790" is not clearly parse-able into companyName[], companyAddress[], companyCity[], companyState[], companyZip without additional rules.
I'd expect more commas.
Consider
3M 255 Century Ave N Maplewood, MN 55119 (company name with digits)
Southwest Airlines P.O. Box 36647 Dallas, Texas 75235 (No street number, PO Box)
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