4

I am working on a project where I have to parse data from user input.

#include <iostream>   // for cin and cout
#include <iomanip>    // for setw()
#include <cctype>     // for toupper()
using namespace std;


int main(){

string playerInput;

cin >> playerInput; 
//Player would input strings like C13,C 6, I1, Z  16, etc...




}
return 0;

I've tried something like this, which kinda works but only if the letter proceeds the number in the string.

int myNr = std::stoi(playerInput);

What my end goal is to grab the letter and number from the string, and place them in a char variable and a integer variable respectively. I am stuck on how to proceed from here and could use some help, thanks!

mirackara
  • 87
  • 1
  • 4
  • 1
    Can you show an input/output example? Do you have to read multiple comma separated strings? Are they on separate lines? – cigien Jul 06 '20 at 01:35
  • A lot depends on how much you can trust the precision of the input. If it is human input, it may miss a space or a comma or such. How tolerant do you want your input parser to be? – Eljay Jul 06 '20 at 02:25

4 Answers4

2

This is the simplest and the shortest way to achieve that (it also ignores spaces and tabs):

int main() {
    char ch;
    int n;
    cin >> ch >> n;

    cout << "ch = " << ch << ", n = " << n << endl;
}

I think that other answers are a bit overcomplicated.

Szymon Bednorz
  • 425
  • 3
  • 10
  • 25
1

You have the right idea in using std::stoi. My code expands your approach:

string playerInput;
getline(cin, playerInput);

char c1 = playerInput[0];
int num = stoi(playerInput.substr(1));

The above code receives an input string, then takes out the first character and uses std::stoi on the rest of the string.

Note that I use std::getline to account for the possibility of there being spaces in the input. If you are doing this repeatedly, you will need to add cin.ignore() after each getline() statement. See this link for more info.

sehe
  • 374,641
  • 47
  • 450
  • 633
Telescope
  • 2,068
  • 1
  • 5
  • 22
  • How would I go about checking the playerInput? For example, if playerInput = "Cz14" It will spit out an invalid argument error code. – mirackara Jul 06 '20 at 01:46
  • Your question implied that the user input would only consist of *one* char and then a number. If the number of chars varies, then let me know and I'll update my answer. – Telescope Jul 06 '20 at 02:21
  • In fact, if the number of `chars` varies, then none of the posted answers would work. We all assumed that the input string only contained one `char`: the first character. – Telescope Jul 06 '20 at 02:24
1

You could do like what you had:

    char letter = playerInput.front();
    playerInput.erase(0);

    int number = std::stoi(playerInput);

Of course, that doesn't allow for spaces. Removing spaces can be quite tedious, but it could be done like:

    playerInput.erase(
            std::remove_if(
                begin(playerInput), end(playerInput),
                [](uint8_t ch) { return std::isspace(ch); }),
            end(playerInput));

Full Demo

Live On Coliru

#include <cctype>   // for toupper()
#include <iomanip>  // for setw()
#include <iostream> // for cin and cout
#include <algorithm> // for remove_if

static bool ignorable(uint8_t ch) {
    return std::isspace(ch)
        || std::ispunct(ch);
}

int main() {
    std::string playerInput;

    while (getline(std::cin, playerInput)) {
        playerInput.erase(
                std::remove_if(
                    begin(playerInput), end(playerInput),
                    ignorable),
                end(playerInput));
                
        if (playerInput.empty())
            continue;

        char letter = playerInput.front();
        playerInput.erase(begin(playerInput));

        int number = std::stoi(playerInput);

        std::cout << "Got: " << letter << " with " << number << "\n";
    }
}

Prints

Got: C with 13
Got: C with 6
Got: I with 1
Got: Z with 16
sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    Added the [Live Demo](http://coliru.stacked-crooked.com/a/73b1cf89c84bf5c0) – sehe Jul 06 '20 at 01:35
  • For contrast, with an actual input parser: **[Live On Coliru](http://coliru.stacked-crooked.com/a/1960383848797d67)** – sehe Jul 06 '20 at 01:41
0

std::cin stops reading input when it encounters a space. You can use std::getline() if your input has spaces. To parse your string, you should check out std::stringstream. It allows you to read from a string as if it were a stream like std::cin.

#include <iostream>   // for cin and cout
#include <iomanip>    // for setw()
#include <cctype>     // for toupper()
#include <sstream>

int main(){

std::string playerInput;
int i;
char c;
 std::getline(std::cin, playerInput); // Remove trailing newline
 std::getline(std::cin, playerInput);
//Player would input strings like C13,C 6, I1, Z  16, etc...
 
//String Stream
std::stringstream playerInputStream(playerInput);
//Read as if you were reading through cin
 playerInputStream >> c; // 
 playerInputStream >> i;



}
return 0;
Amal K
  • 4,359
  • 2
  • 22
  • 44