Gabe
Gabe

Reputation: 1296

How to read a line from file?

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

Answers (8)

che
che

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

Robert Gamble
Robert Gamble

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

Guilherme
Guilherme

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

Jeff Hubbard
Jeff Hubbard

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

FlySwat
FlySwat

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

ppl
ppl

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

Adam Rosenfield
Adam Rosenfield

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

kenny
kenny

Reputation: 22404

fgets() and sscanf() as I remember

Upvotes: 0

Related Questions