Reputation: 1296
I have to read a txt file with lines formated like this:
1: (G, 2), (F, 3) 2: (G, 2), (F, 3) 3: (F, 4), (G, 5) 4: (F, 4), (G, 5) 5: (F, 6), (c, w) 6: (p, f), (G, 7) 7: (G, 7), (G, 7) w: (c, w), (c, w)
Each line will feed a struct with its data (the 5 numbers or letters in it).
What's the best way to read the line and get the strings I want?
I'm currently using a long sequence of conditions using fgetc
but that seems ugly and not very smart.
I can't use arrays because the lines may vary in size if the numbers have two digits.
Upvotes: 2
Views: 3218
Reputation: 12273
fscanf works pretty nice, but you'll have to use string conversions, because chars wouldn't work for numbers with more than one digit.
Isn't this some kind of homework?
#include <stdio.h>
void main(int argc, char **argv) {
FILE * f;
f = fopen(argv[1], "r");
while (1) {
char char_or_num[32][5]; // five string arrays, up to 32 chars
int i;
int did_read;
did_read = fscanf(f, "%32[0-9a-zA-Z]: (%32[0-9a-zA-Z], %32[0-9a-zA-Z]), (%32[0-9a-zA-Z], %32[0-9a-zA-Z])\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
if (did_read != 5) {
break;
}
printf("%s, %s, %s, %s, %s\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
}
fclose(f);
}
Upvotes: 0
Reputation: 109162
#include <stdio.h>
int main (void)
{
char buf[81]; /* Support lines up to 80 characters */
char parts[5][11]; /* Support up to 10 characters in each part */
while (fgets(buf, sizeof(buf), stdin) != NULL)
{
if (sscanf(buf, "%10[^:]: (%10[^,], %10[^)]), (%10[^,], %10[^)])",
parts[0], parts[1], parts[2], parts[3], parts[4]) == 5)
{
printf("parts: %s, %s, %s, %s, %s\n",
parts[0], parts[1], parts[2], parts[3], parts[4]);
}
else
{
printf("Invalid input: %s", buf);
}
}
return 0;
}
Sample run:
$ ./test
1: (G, 2), (F, 3)
2: (G, 2), (F, 3)
3: (F, 4), (G, 5)
4: (F, 4), (G, 5)
5: (F, 6), (c, w)
6: (p, f), (G, 7)
7: (G, 7), (G, 7)
w: (c, w), (c, w)
parts: 1, G, 2, F, 3
parts: 2, G, 2, F, 3
parts: 3, F, 4, G, 5
parts: 4, F, 4, G, 5
parts: 5, F, 6, c, w
parts: 6, p, f, G, 7
parts: 7, G, 7, G, 7
parts: w, c, w, c, w
If the last value in the input is more than 10 characters it will be truncated with no indication of error, if this is not acceptable you can use the %c
conversion specifier as a sixth argument to capture the next character after the last value and make sure it is a closing parenthesis.
Upvotes: 3
Reputation:
Assuming you have the correct variables, this should work:
fscanf(fp, "%[^:]: (%[^,], %[^)]), (%[^,], %[^)])", a, b, c, d, e);
fp is a file pointer and "a" to "e" are char pointers
Upvotes: 0
Reputation: 9902
Basically you'll have to save the position of the file ptr via fgetpos, walk to the end of the line (however you define it), save that size, fsetpos to the previous position, allocate a buffer big enough to hold the line, and then call fread with the new buffer.
Upvotes: 0
Reputation: 175713
I think you could parse it along the lines of:
fscanf(file,"%c: (%c, %c), (%c, %c)", &first,&second,&third,&fourth,&fifth);
Upvotes: 6
Reputation:
#include void f() { FILE* fp; if ( (fp = fopen("foo.txt", "r")) == NULL) { perror("fopen"); return; } char ch[5]; while (fscanf(fp, "%c: (%c, %c), (%c, %c)\n", &ch[0], &ch[1], &ch[2], &ch[3], &ch[4]) == 5) { printf("--> %c %c %c %c %c\n", ch[0], ch[1], ch[2], ch[3], ch[4]); } fclose(fp); }
Upvotes: 0
Reputation: 400602
Use fgets()
:
#include <stdio.h>
int main(void)
{
char line[256];
while(fgets(line, sizeof(line), stdin) != NULL) // fgets returns NULL on EOF
{
// process line; line is guaranteed to be null-terminated, but it might not end in a
// newline character '\n' if the line was longer than the buffer size (in this case,
// 256 characters)
}
return 0;
}
Upvotes: 4