I need to read in a formatted file that looks something like this.
Code: HARK
Name: Oscar
MRTE: Train
etc
At the moment my code looks like this.
FILE *file;
char unneeded[10];
char whitespace[2];
char actual[10];
file = fopen("scannertest.txt","r");
fscanf(file,"%s",unneeded); // this is the identifier and the colon (code:)
fscanf(file,"%[ ]",whitespace); // this takes in the white space after the colon.
fscanf(file,"%s",actual); // this is the value I actually need.
/**
* Do stuff with the actual variable
**/
fclose(file);
This way works for me but I don't think writi开发者_运维知识库ng three fscanf()'s for each line in the text file is the best way to do it, especially as I will be doing it in a loop later.
I tried doing it like this:
fscanf(file, "%s %[ ] %s",unneeded,whitespace,real);
However this gave me weird symbols when I tried printing the output.
The %s
scanf specifier already ignores spaces. If you do
scanf("%s%s", unneeded, actual)
and the input is "Code: HARK", unneeded
will have "Code:" and actual
will have "HARK".
Warning: scanf
is a troublesome function (it's "difficult" to use safely). If you want more safety, specify the maximum number of characters (remember the zero terminator) you are willing to accept into each string
scanf("%9s%9s", unneeded, actual); /* arrays defined with 10 elements */
The best is to use fgets
followed by sscanf
.
Edit after reading a comment to another answer
And remember to *always* check the return value of scanf
.
chk = scanf("%9s%9s", unneeded, actual);
if (chk != 2) /* error reading data */;
In C, the file functions use buffered I/O. This means that fscanf won't be hitting the disk with each call so the performance loss of using 3 calls instead of 1 should be negligible.
However, the best thing to do is get your program working and then if it's too slow measure where the performance bottlenecks are and fix those first. It's not worth it trying to guess what sections of code will cause performance issues.
Your code doesn't work because
fscanf(file,"%s",unneeded);
fscanf(file,"%[ ]",whitespace);
fscanf(file,"%s",actual);
does not do the same thing as
fscanf(file,"%s %[ ] %s", unneeded, whitespace, actual);
it is functionally equivalent
fscanf(file,"%s%[ ]%s", unneeded, whitespace, actual); // No spaces in fmt string
HTH
If you are looking for ways to speed up your code, you could read in your entire file, or a buffer of the file. Reading an entire block at a time would be faster than reading in data as you need it.
You can then use sscanf
on the buffer you read.
I'm a sick person who misses coding in C every now and then. I wrote out something that appears to work:
Contents of test.txt
Code: HARK
Name: Oscar
MRTE: Train
Contents of text.c
#include <stdio.h>
#define MAX_LEN 256
int main(void)
{
FILE *file;
char str_buf[MAX_LEN + 1]; // One extra byte needed
// for the null character
char unneeded[MAX_LEN+1];
char actual[MAX_LEN+1];
file = fopen("test.txt","r");
while(fgets(str_buf, MAX_LEN + 1, file) != NULL)
{
sscanf(str_buf, "%s%s", unneeded, actual);
printf("unneeded: %s\n", unneeded);
printf("actual: %s\n", actual);
}
return 0;
}
Output of compiled code:
unneeded: Code:
actual: HARK
unneeded: Name:
actual: Oscar
unneeded: MRTE:
actual: Train
精彩评论