Home > other >  How to create 2D vector from string input
How to create 2D vector from string input

Time:08-09

I'm very beginner in C and I'm trying to print a 3x3 gameboard from user input string.

I don't know how that board vector function should be implemented. The code would create a 2D vector from user input values and then print gameboard from that vector.

int main()
{

    cout << "Input: ";
    string input_i;
    cin.ignore();
    getline(cin, input_i);

    vector<vector<int>> board // if user input would be "1 2 3 4 5 6 7 8 9" function would make a 2D vector like this
        {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    // and then print 2D board from vector<vector<int>> board
    for (int i = 0; i < board.size(); i  )
    {
        for (int j = 0; i < board[i].size(); j  )
        {
            cout << board[i][j] << " ";
        }
        cout << endl;
    }
}

Would appreciate your help if someone is able to help!

CodePudding user response:

You could do it like this, also introduces you to

  • auto : let the compiler deduce the type
  • const : for things that should not change
  • reference : for now think of this as a pointer to something that cannot be nullptr
  • range based for loops (safer then index based loops)

/

#include <iostream>
#include <sstream>
#include <array>
#include <vector>

// using namespace std; <== NO don't do this, can cause problems in big projects

int main()
{
    std::cout << "Input (9 numbers separated by a spece): ";
    
    std::string input{ "1 2 3 4 5 6 7 8 9" }; // for test start with initialized string
    
    //std::string input;
    //std::cin >> input;
    
    std::cout << "\n";

    // create a string stream from your input, stringstreams can be used to
    // easily get values out of strings with their stream operators.
    std::istringstream is{ input };

    //std::array<std::array<int, 3>, 3> board{}; // fixed size board
    std::vector<std::vector<int>> board(3, std::vector<int>(3)); // runtime sized board
    
    // use a range based for loop, will not go out of bound
    for (auto& row : board)
    {
        for (auto& column : row)
        {
            is >> column; // get next value from input stream and put it in current value
            
            // another option is to use std::cin here directly and read number by number and not ask for the whole string up front.
        }
    }

    // output board, use constant values, output should not change content of board
    for (const auto& row : board)
    {
        for (const auto column : row)
        {
            std::cout << column << " ";
        }
        std::cout << "\n";
    }

    return 0;
}

CodePudding user response:

Your function can be something like this.

std::vector<std::vector<int>> parse_board()
{
    std::vector<std::vector<int>> board(3, std::vector<int>(3));
    for(int i = 0 ; i < 3;   i)
    {
        for(int j = 0; j < 3;   j)
        {
            std::cin >> board[i][j];
        }
    }

    return board;
}

If reading the board is not directly from stdin, but from some intermediate string, you can do this.

std::vector<std::vector<int>> parse_board_from_string(const std::string& str)
{
    std::stringstream str_in(str); // note: #include <sstream>

    std::vector<std::vector<int>> board(3, std::vector<int>(3));
    for(int i = 0 ; i < 3;   i)
    {
        for(int j = 0; j < 3;   j)
        {
            str_in >> board[i][j];
        }
    }

    return board;
}
  • Related