Thread: Reading from file

  1. #1
    Registered User
    Join Date
    Jan 2016
    Posts
    22

    Reading from file

    Hello!
    I have a reading from file inside my program.
    My problem is I'm not sure how to make the program to check if there are either 2 or 4 elements to read in line.
    Basically, it should read from textfile like this:
    A 1 2 (if there are 2 numbers and no more, read them and go to the next line)
    or
    A 1 2 3 4 (if there are 4 numbers read all of them and go to next line)
    so basically the textfile would look for example like
    A 1 2
    A 3 4
    A 7 8 9 10
    (it seperates every element to different variable).

    My program works that in case of 'A' it reads 2 numbers:
    fscanf(file,"%d %d",&i1, &i2);
    But how to make it read 2 numbers if there are 2 numbers, and 4 if there are 4?

    Hope u understood what I meant, thanks for help in advance!

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    The "scanf" family of functions returns the number of items successfully read. Think about how you can use this to your advantage.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Adding to Matt's advice, consider using fgets to read the entire line into a buffer and then sscanf on the buffer.

  4. #4
    Registered User
    Join Date
    Jan 2016
    Posts
    22
    Quote Originally Posted by Matticus View Post
    The "scanf" family of functions returns the number of items successfully read. Think about how you can use this to your advantage.
    Yeah, I made a lot of attempts already but every time I fail something.
    In my mind it looks like
    if fscanf returns 2 (values), then read 2 more values and go further
    if fscanf returns 4 (values), then go further
    Should it look like that in theory? If yes then I must mess up something in code

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Assuming there can either be two or four numbers per line, I would approach it as: Attempt to read the maximum (i.e. four) values. If only two are read, you know you have two. If four are read, you know you have four. Otherwise, an error has occurred.

    If there can theoretically be any number of values on a given line, I would look into solutions other than "scanf" - but your original question implied that it was either two or four values per line only. (If this is not the case, clearly explain the possible inputs so we can offer potentially better methods).

  6. #6
    Registered User
    Join Date
    Jan 2016
    Posts
    22
    Quote Originally Posted by Matticus View Post
    Assuming there can either be two or four numbers per line, I would approach it as: Attempt to read the maximum (i.e. four) values. If only two are read, you know you have two. If four are read, you know you have four. Otherwise, an error has occurred.

    If there can theoretically be any number of values on a given line, I would look into solutions other than "scanf" - but your original question implied that it was either two or four values per line only. (If this is not the case, clearly explain the possible inputs so we can offer potentially better methods).
    Yeah, I meant 2 or 4 values, but actually I'd like also to try to make it for example max 10 numbers. I think scanf will not be enough anymore?

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    "scanf" will work fine for this.

  8. #8
    Registered User
    Join Date
    Apr 2016
    Posts
    3
    someone help me with this please!! i have an exam tomorrow!! plsss help

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by maslayer View Post
    someone help me with this please!! i have an exam tomorrow!! plsss help
    Please stop spamming the board with your begging. You've already received a response in your thread after only ten minutes, which is very good for free help. Don't be selfish.

  10. #10
    Registered User
    Join Date
    Jan 2016
    Posts
    22
    Oh, I forgot to mention important thing.
    I said it looks for example
    A 1 2
    A 3 4
    A 7 8 9 10

    But I forgot to say that every line has a number before it.
    So it looks like
    1 A 1 2
    2 A 3 4
    3 A 7 8 9 10
    4 ...
    5 ...

    And that's where my problem comes from. It reads the number from next line and I want to avoid that.

    #EDIT: That maslayer post isn't mine. I don't know him.

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    If you don't want that first number, you can tell "scanf" to ignore it using an asterisk thusly: "%*d"

    Quote Originally Posted by Pinkysuavo View Post
    #EDIT: That maslayer post isn't mine. I don't know him.
    Yes, I know. My response was directed at them, for posting their nonsense in your thread.

  12. #12
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    [QUOTE=Pinkysuavo;1254527And that's where my problem comes from. It reads the number from next line and I want to avoid that.[/QUOTE]
    That's why I suggested using fgets to read the entire line first, then use sscanf on the line.

    Untested code:
    Code:
    char line[1000];
    
    while (fgets(line, sizeof line, fp) != NULL) {
        int ret = sscanf(line, "%*d %c %d %d %d %d", &c, &w, &x, &y, &z);
        if (ret == 3) {
            // letter and two ints
        } else if (ret == 5) {
            // letter and four ints
        } else {
            // error
        }
    }
    EDIT: A little test program
    Code:
    /*
    1 A 1 2
    2 A 3 4
    3 A 7 8 9 10
    x x x x
    */
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        FILE *fp = fopen("cb_reading_from_file.c", "r");  // this source file
        fgetc(fp); fgetc(fp); fgetc(fp);  // skip first line
    
        char line[1000], c;
        int w, x, y, z;
    
        while (fgets(line, sizeof line, fp) != NULL) {
            int ret = sscanf(line, "%*d %c %d %d %d %d", &c, &w, &x, &y, &z);
            if (ret == 3) {
                printf("2 vals: %c %d %d\n", c, w, x);
            } else if (ret == 5) {
                printf("4 vals: %c %d %d %d %d\n", c, w, x, y, z);
            } else {
                fprintf(stderr, "Bad line: %s", line);
                exit(EXIT_FAILURE);
            }
        }
    
        fclose(fp);
    
        return 0;
    }
    Output:
    Code:
    2 vals: A 1 2
    2 vals: A 3 4
    4 vals: A 7 8 9 10
    Bad line: x x x x
    Last edited by algorism; 04-26-2016 at 10:02 AM.

  13. #13
    Registered User
    Join Date
    Jan 2016
    Posts
    22
    @UP
    That helped, thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 11-27-2013, 12:24 PM
  2. Replies: 0
    Last Post: 03-21-2013, 03:31 PM
  3. Replies: 3
    Last Post: 11-28-2012, 09:16 AM
  4. Replies: 3
    Last Post: 07-17-2011, 03:51 AM
  5. Replies: 13
    Last Post: 05-31-2009, 11:30 AM