2010-11-12 6 views
0

question rapide ici. Je me demande comment créer un vecteur 2D à partir de l'entrée de l'utilisateur. Pour un projet, je stocke mon "tableau" comme un vecteur 2D, et l'utilisateur va entrer la hauteur et la largeur de celui-ci, ainsi que peut-être la configuration de départ.Créer un vecteur 2D à partir de l'entrée en C++

Si mon conseil est stocké comme:

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

je vais devoir initialiser les paramètres donnés et (si l'utilisateur fournit les informations), remplir la carte avec des morceaux. L'utilisateur saisira toutes ces informations sur 1 ligne, via 1 cin. Alors comme ça ...

Please type the board config: 3 3 

ou

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

ou

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

Avec le dernier étant un exemple d'entrée mal. Le premier exemple créerait un vecteur 2D, 3 par 3. Le second créerait un vecteur 2D, 3 par 3, et remplirait le tableau avec la position donnée. Dans ce cas, "." est un 0, "X" est un 1, et "O" sera un -1. C'est la partie avec laquelle j'ai le plus de problèmes. je pouvais stocker dans une chaîne, mais il semble que passer par et l'analyse que ce serait une douleur dans le cul ...

+0

L'analyse syntaxique semble banale ... quel est le problème exact? –

Répondre

2

Je voudrais essayer de déduire les dimensions de l'entrée de l'utilisateur.

Une séance exemple:

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

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

Ensuite, vous scanner la première ligne pour trouver la largeur, vérifiez chaque ligne pour les caractères valides et la même largeur, et compter les lignes pour trouver la hauteur.

0

je pouvais stocker dans une chaîne, mais il semble que en passant par et l'analyse ce serait une douleur dans la crosse ...

Pourquoi? C'est une seule chaîne if/else ou switch.

Et tôt ou tard, vous serez fatigué de la gestion des vecteurs de vecteurs. Je mettrais le tableau entier dans un seul vecteur et l'adresse y * width + x. Il pourrait même devenir une classe à part dans le futur:

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

Les spécifications d'exception ne sont pas seulement une mauvaise pratique, mais sont déconseillées en C++ 0x. – GManNickG

+0

Retiré. Est-ce parce qu'ils ne garantissent pas la sécurité des exceptions? – aib

+0

Les spécifications d'exception présentent des problèmes de performances et sont plus complexes qu'elles ne le sont. Voir http://www.gotw.ca/gotw/082.htm pour une bonne discussion. – beldaz

1

Vous pouvez utiliser une carte où la clé est une paire std :: des coordonnées de la carte lues depuis cin comme entiers. La représentation de la valeur peut alors être un int ou un caractère et est facilement accessible. Ensuite, vous pourriez faire des choses comme ...

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

Partez déjà, pour l'amour du ciel! Si tout ce que vous autorisez est '.', 'X' et 'O', alors tout ce que vous avez à faire est de sauter un espace. (Si vous aimez vos utilisateurs, vous pourriez également envisager d'utiliser des lettres minuscules.)

0

Pseudocode qui conduit probablement à une roue carrée.

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

Voici une méthode utilisant cin et ses mécanismes:

#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 

} 

Mais fot cette quantité d'effort que vous pourriez aussi bien le lire dans un std :: string et d'écrire un analyseur et obtenir plus avec. Si ce sera plus rapide et plus facile de faire ce que vous voulez si vous obtenez une mauvaise entrée.

Questions connexes