Thread: Equivalent of sscanf

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    12

    Equivalent of sscanf

    I'm transitioning from C to C++ and am apparently having issues with certain things. In my C code, I have something that looks like this:

    Code:
    char grid[2][2];
    for(int y=0; y<2; y++)
    {
        while(scanf("%c %c", &grid[y][0], &grid[y][1]) != 2)
        {
            printf("Please format your input as 2 characters separated by a space\nPress a key to try again\n");
            getch();
        }
    }
    How would I do the same in C++? I tried using cin << grid[y][0] << grid[y][1], but if I type "lolol" or something it doesn't read the data the way I want it to.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Your pointing your thingamajigs in the wrong whatchacallit (sorry to go all technical on you) :
    Code:
        cin >> grid[y][0] >> grid[y][1];
    << is the "insertion" operator, which inserts data into an output stream.
    >> is the "extraction" operator, which extracts data from an input stream.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >> it doesn't read the data the way I want it to.

    I would hope not, since the data is clearly wrong.

    By default the I/O objects will become zombies if something goes wrong. They can throw exceptions but you have to program which exceptions to throw. In the meantime, you have code like this which will reset the state of I/O objects and generally handle bad input. C++ does give you plenty of methods to work with so you can figure out what happened in the aftermath of an operation and deal with it. iostream - C++ Reference

    Code:
    #include <iostream>
    #include <cstddef> // for BUFSIZ
    while (!(cin >> grid[y][0] >> grid[y][1])) {
        cin.clear();
        cin.ignore(BUFSIZ, '\n');
    }

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    12
    Sorry about the wrong thingamajigs and the lack of proper description. That was just example code to quickly show what I'm looking for.

    What I'm actually doing is a loop on both x and y and I don't know how to read it without scanf. Here's what I've been trying:
    Code:
    for(int y=0; y<gridsize; y++)
    {
        cout << "Map the grid line " << y << endl;
        for(int x=0; x<gridsize; x++) //a perfect square grid
        {
            while(grid[y][x] != 'O' && grid[y][x] != '.')
            {
                cin.get(grid[y][x]);
                if(grid[y][x] != 'O' && grid[y][x] != '.') { cout << "Please enter a O or a ." << endl; }
                cin.ignore(256, ' ');
            }
        }
    }
    But while I'm inputting data in the program, it gets all buggy with the newlines and the spaces. I want my program window to look like this:
    Code:
    Map the grid line 0
    O b
    Please enter a O or a .
    O .
    Map the grid line 1
    ...
    Right now I can bug it out by doing something like this
    Code:
    Map the grid line 1
    butt
    Please enter a O or a .
    Please enter a O or a .
    Please enter a O or a .
    Please enter a O or a .
    O.O
    ... //The program is ok with this even though it has too many characters
    With scanf, I can make sure I'm only reading one character and that there is a space inbetween, and if I typed something like "butt O" it would read b and O. I'm looking to do that with C++.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Your description of scanf is incorrect. It won't make sure there's a space between the characters or just read the first letters of the first two words. You must have dreamt that. I often do.

    Try this:
    Code:
    #include <stdio.h>
    int main(void) {
        char a, b;
        scanf("%c %c", &a, &b);
        printf("[%c] [%c]\n", a, b);
        return 0;
    }
    Input: hello there
    Ouput: [h] [e]
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    12
    Oops! T.T. I think this would work the way I want but I haven't tried it:
    Code:
    char v[2];
    scanf("%[^' '] %c", &v[0], &v[1]);
    Anyway that just further verifies I need to learn to do this, lol
    Last edited by Alexander Edgar; 09-06-2012 at 05:56 PM.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Interesting trick, but unfortunately it's a buffer overflow.
    Code:
    #include <stdio.h>
    int main(void) {
        char a, b, c='x', d='x';
        scanf("%[^ ] %c", &a, &b);
        printf("[%c] [%c] [%c] [%c]\n", a, b, c, d);
        return 0;
    }
    Input: hello there
    Output: [h] [t] [e] [l]

    Note that c and d were overwritten.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    12
    I guess the best way to do that in C would be to read the entire line, separate spaces with strtok, and then read only the first letter of each token.

    Back to my original question though - how do I read letters, in a for loop, separated by a space in C++? cin.get(grid[y][x]); gets me the letter and then I can verify it, but how do I make sure everything is separated by a space, and how do I ignore full words? cin.ignore(256, ' '); didn't seem to do the trick.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Just read the tokens into std::string variables and verify that they are single characters after the fact.

    Code:
    std::string letter1;
    std::string letter2;
    std::cin >> letter1 >> letter2;
    if (letter1.size() == 1 && letter2.size() == 1)
    {
        // you have two letters
        char l1 = letter1[0];
        char l2 = letter2[0];
        // do something with l1, l2
    }
    else
    {
        // there was an input error
    }
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Alexander Edgar
    how do I read letters, in a for loop, separated by a space in C++? cin.get(grid[y][x]); gets me the letter and then I can verify it, but how do I make sure everything is separated by a space, and how do I ignore full words? cin.ignore(256, ' '); didn't seem to do the trick.
    Use brewbuck's suggestion in post #9, except that you use it with getline:
    std::string letter;
    Code:
    while (std::getline(std::cin, letter, ' '))
    {
        if (letter.size() == 1)
        {
            // ...
        }
        else if (letter.empty())
        {
            // separated by multiple spaces - invalid input?
        }
        else
        {
            // ignore full word
        }
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You could also do
    Code:
    char letter[2], temp;
    if (std::cin >> letter[0] && std::cin >> temp && temp == ' ' && std::cin >> letter[1])
    	// Success!
    else
    	// The user entered some input in the wrong format and/or type. Clear input buffer and try again.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. An equivalent of sscanf
    By g4j31a5 in forum C++ Programming
    Replies: 5
    Last Post: 07-04-2007, 01:27 AM
  2. C equivalent of vector
    By Hunter2 in forum C Programming
    Replies: 8
    Last Post: 09-10-2005, 09:24 AM
  3. STL map<> Equivalent
    By nickname_changed in forum C# Programming
    Replies: 1
    Last Post: 02-27-2004, 06:32 AM
  4. %3s equivalent for C++
    By mackol in forum C++ Programming
    Replies: 4
    Last Post: 03-17-2003, 06:10 AM
  5. what's the c equivalent to this asm code
    By *ClownPimp* in forum C++ Programming
    Replies: 4
    Last Post: 01-18-2002, 12:03 AM