#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0

    Scanf multi-line input


    New to programming here and I ran into a problem before I've even written 5 lines......

    Im trying to take 2 lines of data (made up of 5 pairs of space seperated characters) from STDIN. Eg.

    a1 b2 c3 ...
    d1 e2 f3 ...

    Each line of first and second characters needs to an array - 2 arrays for first characters and 2 for second characters.

    Any suggestions?
    As you can see by the difficulty of my problem, Im not particularly proficient in C yet. So the simple the answer, the better :thumbs:

    Thanks in advance!!

    Dave
  2. #2
  3. No Profile Picture
    I haz teh codez!
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Dec 2003
    Posts
    2,540
    Rep Power
    2337
    One option is to use fgets() to get each line into a string and then using sscanf() to parse said string.
    I ♥ ManiacDan & requinix

    This is a sig, and not necessarily a comment on the OP:
    Please don't be a help vampire!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by ptr2void
    One option is to use fgets() to get each line into a string and then using sscanf() to parse said string.
    Thanks.

    How would that look then?

    To clarify, Im not sure how to move to the second line so get the data there
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,089
    Rep Power
    2222
    Basically, scanf doesn't care (dependent on your not doing anything fancy in the format string). You tell it to read in three values and it will read in three values. Regardless of whether all three are on one line of input or each on its own separate line or with a dozen empty lines between each number's own separate line. It even doesn't care if the three values are part of a hundred numbers on the same line of input. It just does not care about those details.

    All it does is read in the values you tell it to and then it stops, leaving whatever follows in the input buffer to be processed by the next scanf call -- what it's guaranteed to leave in the input buffer is the newline from when you hit the Enter key, which is why scanf("%c",&ch) will appear to fail, because it reads the next character regardless of whether it's whitespace.

    Now, if you want to restrict the input such that the three values all need to be in the same line of input, then you read in the entire line with fgets reading from the standard input file (stdin) and use sscanf on that input string, testing the return value of the sscanf to ensure that all three conversions succeeded.

    For more information on fgets and sscanf, RTFM ("Read The Manual"). If you don't have a help file or man pages for your compiler, then consult one of the literally thousands of man pages that are on-line (eg, Google on man page fgets).
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by dwise1_aol
    Basically, scanf doesn't care (dependent on your not doing anything fancy in the format string). You tell it to read in three values and it will read in three values. Regardless of whether all three are on one line of input or each on its own separate line or with a dozen empty lines between each number's own separate line. It even doesn't care if the three values are part of a hundred numbers on the same line of input. It just does not care about those details.

    All it does is read in the values you tell it to and then it stops, leaving whatever follows in the input buffer to be processed by the next scanf call -- what it's guaranteed to leave in the input buffer is the newline from when you hit the Enter key, which is why scanf("%c",&ch) will appear to fail, because it reads the next character regardless of whether it's whitespace.

    Now, if you want to restrict the input such that the three values all need to be in the same line of input, then you read in the entire line with fgets reading from the standard input file (stdin) and use sscanf on that input string, testing the return value of the sscanf to ensure that all three conversions succeeded.

    For more information on fgets and sscanf, RTFM ("Read The Manual"). If you don't have a help file or man pages for your compiler, then consult one of the literally thousands of man pages that are on-line (eg, Google on man page fgets).
    I'm starting to get the idea of what to do, but I'm not sure how to do it.

    Its all good and well to say look through the thousands of forums and pages and blah blah blah. However so far, after looking at probably 50 or 60 forums detailing how to do something like what Im asking, I can say I've understood none of it because its written by people more experienced than me and intended for people more experienced than me. This is why Im asking for someone to show me in simple terms how to do this.
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,364
    Rep Power
    1870
    So given an input of
    a1 b2 c3 ...

    What are you expecting to store?
    There are a multitude of ways this could go.

    Eg
    Code:
    char first[] = "abc...";
    char second[] = "123...";
    or
    Code:
    char first[][3] = {
      "a1",
      "b2",
      "c3",
      ...
    };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,089
    Rep Power
    2222
    You don't have to read through thousands of man pages. You only need to read one for each function. Just pick the first one of the tens of thousands found. The man page for fgets will show you how to use fgets; many man pages include an example. Same thing with sscanf.

    sscanf is part of the *scanf family, which are all essentially the same only they get input from different sources. scanf gets input from the standard input file, stdin, which reads the keyboard. sscanf gets its input from a string (hence the 's'). fscanf gets its input from a file (hence the 'f'). *printf is the same way. fgets also (though avoid gets), in that it gets a string from a file, which you can specify to be stdin.

    Call fgets to read in a string. Pass that string to sscanf to read the three values out of it. When you want to read the next line, just call fgets again followed by sscanf. That is how to do it. And there are many example of this on-line; STFW ("Search The Web"). When you find one and cannot understand it, then bring it here for us to explain it. For that matter, since you say that you've visted 50 or 60 forums that detailed how to do it, then tell us what part of those explanations you didn't understand. We need something to work with.

    You might also want to read that link in ptr2void's signature. That one about "help vampires."
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by salem
    So given an input of
    a1 b2 c3 ...

    What are you expecting to store?
    There are a multitude of ways this could go.

    Eg
    Code:
    char first[] = "abc...";
    char second[] = "123...";
    or
    Code:
    char first[][3] = {
      "a1",
      "b2",
      "c3",
      ...
    };
    Thank you for being the first person to try understand my problem.

    Basically I want to store the first character (a, b, c) of each set in a single array, L1C1 say. Then take the second character (1, 2, 3) of each set and store that in a single array - L1C2. Then do the same for the second line - L2C1 and L2C2. From there I'm doing some comparisons and manipulations ect.
    But what Im asking is how do I get the second line of data. I have a working program now that takes one line, but its getting the second line that I cant do.

    Can you show me how to do this in actual code, not because Im lazy but because I dont know how to write it.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    886
    Just do whatever you did for the first line a second time. Show us the code you have, it would be easier for us to help you.
    I no longer wish to be associated with this site.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by jwdonahue
    Just do whatever you did for the first line a second time. Show us the code you have, it would be easier for us to help you.
    This is what I have thus far:

    Code:
       char L1C1[ 4 ] = {};
       char Space[ 3 ] = {}; 
       int L1C2[ 4 ] = {};
       
       scanf( "%c%c%c%c%c%c%c%c%c%c%c%c%c%c", &L1C1[ 0 ], &L1C2[ 0 ], &Space[ 0 ], &L1C1[ 1 ], &L1C2[ 1 ], &Space[ 1 ] );
    There are actually 5 sets of data but to shorten the code example I've trimmed it a bit. You get the general gist of what I'm doing.
  20. #11
  21. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,364
    Rep Power
    1870
    Well something like
    Code:
    for ( i = 0 ; i < 4 ; i++ ) {
      scanf( "%c%c%*c, &L1C1[ i ], &L1C2[ i ] );
    }
    would allow you to read the same thing without copy/pasting too many %c's.

    Note the last one %*c means read a single character, but don't store it anywhere.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by salem
    Well something like
    Code:
    for ( i = 0 ; i < 4 ; i++ ) {
      scanf( "%c%c%*c, &L1C1[ i ], &L1C2[ i ] );
    }
    would allow you to read the same thing without copy/pasting too many %c's.

    Note the last one %*c means read a single character, but don't store it anywhere.
    Ahhh, that makes sense. Thanks a ton!!

    Im guessing it'd be better to use 2 arrays with 10 elements each instead of 4 arrays with 5 elements each then?

    Thanks again

IMN logo majestic logo threadwatch logo seochat tools logo