2010-11-12 2 views
0

быстрый вопрос здесь. Мне интересно, как создать 2D-вектор из пользовательского ввода. Для проекта я сохраняю свою «плату» как 2D-вектор, и пользователь вводит ее высоту и ширину, а также , возможно, начальную конфигурацию.Создать 2D-вектор из ввода в C++

Если моя доска хранится как:

vector<vector<int> > myBoard(width, vector<int> (height)); 
//Not sure how to get width and height from input... 

мне нужно будет инициализировать его с заданными параметрами и (если пользователь предоставляет информацию), заполнить доску с кусочками. Пользователь будет вводить всю эту информацию в 1 строке, через 1 cin. Так как это ...

Please type the board config: 3 3 

или

Please type the board config: 3 3 . . . . . . X . O 

или

Please type the board config: 3 3 ABFDFL($%$ 

С последним из которых является примером плохого входа. В первом примере будет создан 2D-вектор, 3 на 3. Второй будет создавать 2D-вектор, 3 на 3, и заполнить доску заданной позицией. В этом случае, "." является 0, «X» равно 1, а «O» будет равным -1. В этой части у меня больше всего проблем. я мог хранить его в строку, но, кажется, переживает и анализа, было бы боль в приклад ...

+0

Разбор по этому поводу звучит тривиально ... какая именно проблема? –

ответ

2

Я бы попытался вывести размеры из пользовательского ввода.

Пример сеанса:

A board consists of characters ., X or O. 
An example board: 
.XO 
... 
X.. 

Enter the board, end with two Returns: 
..... 
..XO. 
.XXX. 
OOOOO 
..... 

Тогда вы отсканировать первую строку, чтобы найти ширину, проверить каждую строку для допустимых символов и той же ширины, и подсчет строк, чтобы найти высоту.

0

Я мог бы хранить его в строку, но кажется, что переживает и синтаксический анализ было бы болью в прикладе ...

Почему? Это единственная цепочка if/else или switch.

И рано или поздно вы устанете от управления векторами векторов. Я бы поставил всю доску в один вектор и обратился к ней y * width + x. Он может даже стать самостоятельным классом в будущем:

Piece board::getPieceAt(int x, int y) const 
{ 
    ... 
} 
+0

Спецификации исключения - это не только плохая практика, но и устаревшая в C++ 0x. – GManNickG

+0

Удалено. Это потому, что они не гарантируют безопасность исключений? – aib

+0

Спецификации исключений имеют проблемы с производительностью и являются более сложными, чем они стоят. См. Http://www.gotw.ca/gotw/082.htm для хорошего обсуждения. – beldaz

1

Вы можете использовать карту, где ключ представляет собой std :: пару координат платы, считанных cin целыми числами. Тогда представление значения может быть int или char и легко доступно. Тогда вы могли бы делать такие вещи, как ...

if(board[std::pair(x,y)] == '.') 
    //do something; 
1

Разберитесь с ним уже, ради всего святого! Если все, что вы разрешаете, это «.», «X» и «O», то в основном все, что вам нужно сделать, это пропустить пробелы. (Если вы любите своих пользователей, вы можете также рассмотреть возможность ввода строчных букв.)

0

Псевдокод, который, вероятно, ведет к квадратному колесу.

getline(cin, board); 

find location of first space: board.find(' '); 
assign this to size_t height 
extract the digit(s) to a sting (or vector?): board.substr(0, height) 
atoi this string for the height 
cut this from the string: board = board.substr(height) 
repeat for width 
initialize the realBoard vector with width and height 

if board still has chars, start filling the board 
initialize two ints for the vector coordinates 
initialize another for putting numbers onto the board 

until you get to the end of board 
send board[ i ] to a switch 
as you said, o/O = -1; x/X = 1; ./default = 0 
(unless you want bad input to interrupt execution) 
put the value into realBoard[ h ][ w ] 
add one to w; 
if it is above width, make it 0, add one to h 
if h > height, stop this function 
0

Вот метод, использующий ЦИН и его механизмы:

#include <stdio.h> 
#include <iostream> 
#include <vector> 
#include <limits> 
#include <ctype.h> 


using namespace std; 


int main(){ 
    int x; 
    int y; 
    bool done = false; 

    vector<int> inputs; 
    char holdValue; 


    while (!done) 
    { 
     inputs.clear(); 
     cout << "Enter Data:" << endl; //something more descriptive then then this 
     cin >> x >> y; 
     if(cin.fail()) 
     { 
      cin.clear(); 
      cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
      cout << "Error with your input" << endl; 
      continue; 
     } 

     int i = 0; 
     bool error = false; 
     for (; i < (x * y) && error != true ; ++i) 
     { 
      cin >> holdValue; 
      if(cin.fail()) 
      { 
       cin.clear(); 
       cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
       cout << "Error with your input" << endl; 
       error = true; 
      } 
      switch(toupper(holdValue)) 
      { 
       case 'X': 
        inputs.push_back(1); 
        break; 

       case 'O': 
        inputs.push_back(-1); 
        break; 

       case '.': 
        inputs.push_back(0); 
        break; 

       default: 
        cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
        cout << "Error with your input" << endl; 
        error = true; 
        break; 
      } 
     } 

     if(i >= (x * y) && error != true) 
     { 
      done = true; 
     } 
    } 

    //At this piont you have a vector to do with as you please 

} 

Но фот такого количества усилий, вы могли бы также прочитать в станде :: строку и написать парсер и покончите с. Если будет быстрее и будет легче делать то, что вы хотите, если вы ошибаетесь.

Смежные вопросы