c++ 字符串迭代器并将字符传递给其他方法

ajsxfq5m  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(166)

我有一个小的sink the fleet程序,其中我有一个函数,它将字符串作为输入,然后为玩家创建船只。
输入字符串格式始终为B-A3-S,这意味着Shiptype为Battleship(B),从坐标A3开始向南(S)。在同一个字符串中可以有多个坐标,并且它们之间总是至少有一个空格,例如:B-A3-SC-D8-N。类型是枚举值(Battleship,Destroyer,Cruiser,Submarine)。
我想我可以使用迭代器逐个循环字符串字符,并将当前字符传递给返回ShipType的函数。但我一直得到错误和异常EXCEPTION_WRONG_SHIP_TYPE;
我只是在学习如何使用指针和类,所以我不确定我的问题在哪里。
Player Class方法:

void Player::addShips(string ships) {
    string::iterator it; //iterator to go through string
    //ship attributes 
    ShipType type;
    Coordinate pos; 
    Orientation o;

    for (it = ships.begin(); it != ships.end(); it++) {
        if ((*it == ships.at(0) && isalpha(ships[*it])) || (isalpha(ships[*it]) && isspace(ships[*it-1]))) { 
            type = Ship::typeFromChar(ships[*it]);  
        } else if (ships[*it] == '-') {
         ...//more conditions for different situations
        } 
    }
}

类发运具有方法

ShipType Ship::typeFromChar(char type) {
    ShipType st;
    if (type == 'B') { 
        st = BATTLESHIP;
    } else if (type == 'D') {
        st = DESTROYER;
    } else if (type == 'C') {
        st = CRUISE;
    } else if (type == 'S') {
        st = SUBMARINE;
    } else { 
        throw EXCEPTION_WRONG_SHIP_TYPE; //
    }
    return st;
}

在main中,addShips()的调用方式如下:

Player player1("Jack");
try {
        string ships="B-B3-E S-J10-N   C-D7-W  D-A1-S";
        player1.addShips(ships);
    }
    catch (Exception e) {
        Util::error(ERR_SHIPS);
        Util::debug(e);
        return;
    }
vwkv1x7d

vwkv1x7d1#

使用ships[*it]是错误的。it是一个迭代器,不是一个索引。并且取消引用它将返回字符串中的当前字符,而不是字符串的索引。
只需单独使用it,例如:

void Player::addShips(string ships) {
    string::iterator it; //iterator to go through string
    //ship attributes 
    ShipType type;
    Coordinate pos; 
    Orientation o;

    for (it = ships.begin(); it != ships.end(); ++it) {
        if ((it == ships.begin() && isalpha(*it)) || (isalpha(*it) && isspace(*(it-1)))) { 
            type = Ship::typeFromChar(*it);
        } else if (*it == '-') {
         ...//more conditions for different situations
        } 
    }
}

也就是说,从输入string中解析出值的更简洁的方法是使用istringstream读取由空格分隔的每个坐标,并使用std::sscanf()解析每个坐标的各个分量,例如:

#include <string>
#include <sstream>
#include <cstdio>
using namespace std;

void Player::addShips(string ships) {
    istringstream iss(ships);
    string ship;
    while (iss >> ship) {
        char cType, cCoord[3], cOrientation;
        if (sscanf(ship.c_str(), "%c-%2s-%c", &cType, cCoord, &cOrientation) == 3)
        {
            ShipType type = Ship::typeFromChar(cType);
            // ...
        }
    }
}

相关问题