1

I have a .txt file as:

A B C
England vs autralia
2004
100
D E F
japan vs argentina
3045
140
D E F
india vs pakistan
2012
150
J F G
south africa vs india
1967
100
K GHD D
australia vs pakistan
1993
453
Z E Q
pakistan vs england
2013
150  

I want to read it and store in variables. (each line goes to a single variable).

I have this code but it read's one line at a time and as a string.

if ( file != NULL )
{
    i=1;
    char line [ 100 ]; /* line size */
    while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
        {
            fputs ( line, stdout ); /* write the line */
            i++;
        }
    fclose ( file );
}  

Actually I want to read 4 lines at a time. but seems impossible. So I can put the 4 line in a single line separated by a space but in that case scanning multi-word strings will not be possible.

So,How do I do this?

mrudult
  • 2,480
  • 3
  • 35
  • 54
  • `fgets ( line, stdout );` you probably mean fputs() here. – wildplasser Oct 27 '13 at 12:25
  • @wildplasser yup. this is a code I got on SO. check the updated question. – mrudult Oct 27 '13 at 12:26
  • I don't care how you got it, it just looks wrong, and the compiler will *at least* issue a warning. BTW: have you considered a loop? – wildplasser Oct 27 '13 at 12:34
  • 2
    If each 4 lines build a single entity then it is recommendable to have them in a single row and have them separated by some delimiter, this format is know as [csv](http://en.wikipedia.org/wiki/Comma-separated_values) – A4L Oct 27 '13 at 12:48
  • 1
    @A4L: that is debatable. A multi-line format is easyer to read and write: no quoting/escaping of the comma or embedded quotes is needed, the only special character is the '\n'. – wildplasser Oct 27 '13 at 13:13
  • @wildplasser I agree with you, `csv` is not that trivial as it sound, but it is widely spread and has lot of support in almost every language and can be processed by lots of tools too. As you said it's debatable and I find your approach is nice if there is always 4 lines for each record or at least an empty line for data that is not available whereas in csv you have one record = one csv-row (not text row), so OP needs to know what's best for his use case! – A4L Oct 27 '13 at 13:40
  • I know about csv. Been there. The point is: I can write a robust multi-line parser like this in about ten minutes. For csv, it will take about an hour. Or maybe a day, if I have to handle the various dialects of quoting and escaping that exist. (or the lack of escaping, such as in the microsoft "products" ) – wildplasser Oct 27 '13 at 13:49
  • @wildplasser *I know about csv.* I hope you didn't think I doubted that ;-) . What I meant with *widely spread* and *support* is that one should use an existing library for csv to finish the work in 10 mins ;-) . If I had to choose between multi line parsing and csv parsing then I would go with multi line too! – A4L Oct 27 '13 at 15:32

2 Answers2

3

Use a counter to determine on which of the four lines you are:

#include <stdio.h>
#include <string.h>

void doit( FILE *file)
{
char line [ 100 ]; /* line size */
unsigned iii;
size_t len;

    for(iii=0;  fgets ( line, sizeof line, file); iii++ ) /* read a line */
        {
        len = strlen(line);
        while (len && line[len-1] == '\n') line[--len] = 0;
        switch (iii % 4) {
        case 0: /* handle first line here */
               break;
        case 1: /* handle second line here */
               break;
        case 2: /* handle third line here */
               break;
        case 3: /* handle fourth line here */
               break;
                }
        }
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • Won't this scan all the lines as `strings`? – mrudult Oct 27 '13 at 12:50
  • Yes. Initially every line is a string. but you could add specialised code in each of the cases, for example the third line (`case 2:`) looks like a year, and the fourth also looks numeric. Scan the string with sscanf() or atoi() or strtol() or whatever you need. – wildplasser Oct 27 '13 at 12:55
  • it's skipping every alternate line. :/ – mrudult Oct 27 '13 at 13:30
  • No it doesn't. Note: I moved the `iii++` into the for() statement, where it belongs. – wildplasser Oct 27 '13 at 13:35
  • might be the stray `\n` of `fgets()` causing the issue. – mrudult Oct 27 '13 at 14:21
  • There is no stray '\n'. At least not in the data you provided. – wildplasser Oct 27 '13 at 14:23
  • You should initialise the count variable to 0, not to 1. BTW: it effectively shadows the `i` variable, you could remove `count` and replace the final condition by `if (i % 4 == 3) {...}` BTW: *why* do you insist on the 1-letter `i` variable, it is very hard to find (and replace) ? – wildplasser Oct 27 '13 at 14:55
  • I don't think the problem is with the `i` or `count` variable. Did u try running the code? – mrudult Oct 27 '13 at 15:02
  • The problem **is** with the count varable; I don't need to run a program to spot simple errors like that. Have you tried running _my_ code ? It runs like a charm! – wildplasser Oct 27 '13 at 15:49
0

Read it line by line, and as the format seems to be fixed you always know what types there are on each line.

So e.g. like this pseudo-code:

while (continue_reading)
{
    // E.g. "A B C"
    get_line()
    parse_line_into_three_string()

    // E.g. "England vs autralia"
    get_line()
    parse_whole_line_as_a_single_string()

    // E.g. "2004"
    get_line()
    parse_line_as_a_number()

    // E.g. "100"
    get_line()
    parse_line_as_a_number()

    do_something_with_all_data()
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Didn't get u. How is that possible? It reads file line by line so how will it scan 4 lines at a time? –  Oct 27 '13 at 12:31
  • @xmpirate Read one line, parse it, read next line, parse it, and so on. – Some programmer dude Oct 27 '13 at 12:35
  • @mrudult The pseudo-code I have posted should be enough for you to get started. You already know about [`fgets`](http://en.cppreference.com/w/c/io/fgets), now I recommend you learn [`sscanf`](http://en.cppreference.com/w/c/io/fscanf). – Some programmer dude Oct 27 '13 at 12:36