2017-02-02 4 views
0

Как разбить строку на две части после назначения операции математическому оператору? К примеру 4567 * 6789 Я хочу, чтобы разбить строку на три части Первых: 4567 Операции: * Второе: 6789 Входного от текстового файлаСплит-строка с математическим выражением

char operation; 
while (getline(ifs, line)){ 

    stringstream ss(line.c_str()); 
    char str; 

    //get string from stringstream 
    //delimiter here + - */to split string to two part 

    while (ss >> str) { 
     if (ispunct(str)) { 
      operation = str; 
     } 
    } 
} 
+0

Вы, вероятно, нужен парсер. Посмотрите на як или бизон. –

+0

Возможный дубликат [Разделить строку на C++?] (Http://stackoverflow.com/questions/236129/split-a-string-in-c) – Jonas

+0

Спасибо, что я узнал, что поток строк прекращает чтение при встрече другого типа. –

ответ

2

Может быть, просто, может быть, думая это, мы можем придумать решение.

Мы знаем, что operator>> прекратит обработку при столкновении с символом, который не является цифрой. Поэтому мы можем использовать этот факт.

int multiplier = 0; 
ss >> multiplier; 

Следующие символы не являются цифрами, поэтому они могут быть символом оператора.
Что произойдет, если мы читаем в характере:

char operation = '?'; 
ss >> operation; 

О, я забыл упомянуть, что operator>> будет пропускать пробелы по умолчанию.

Наконец, мы можем ввести второй номер:

int multiplicand = 0; 
ss >> multiplicand; 

Чтобы подтвердить, давайте печатать то, что мы читаем в:

std::cout << "First Number: " << multiplier << "\n"; 
std::cout << "Operation : " << operation << "\n"; 
std::cout << "Second Number: " << multiplicand << "\n"; 

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

Edit 1: Более сложный
Вы всегда можете получить более сложный и использовать анализатор, лексера или написать свой собственный. Хорошим методом реализации является использование конечного автомата.

Например, вы должны прочитать один символ, а затем решить, что с ним делать в зависимости от состояния. Например, если символ представляет собой цифру, вы можете создать номер. Для символа (кроме пробела) преобразуйте его в токен и сохраните его где-нибудь.

Есть деревья синтаксического разбора и другие структуры данных, которые могут облегчить работу синтаксического анализа. Там также существуют библиотеки парсинга, такие как boost::spirit, yacc, bison, flex и lex.

0

Один из способов:

char opr; 
int firstNumber, SecondNumber; 
ss>>firstNumber>>opr>>SecondNumber; 

вместо:

while (ss >> str) { 
    if (ispunct(str)) { 
     operation = str; 
    } 
} 

Или с помощью regex для сложных expersions. Here - пример использования регулярных выражений в математических выражениях.

0

Если у вас есть строка под рукой, можно просто разбить строку на левую и правую на месте оператора следующим образом:

char* linePtr = strdup("4567*6789"); // strdup to preserve original value 
char* op = strpbrk(linePtr, "+-*"); 
if (op) { 
    string opStr(op,1); 
    *op = 0x0; 
    string lhs(linePtr); 
    string rhs(op+1); 
    cout << lhs << " " << opStr << " " << rhs; 
} 
0

простое решение было бы использовать sscanf:

int left, right; 
char o; 
if (sscanf("4567*6789", "%d%c%d", &left, &o, &right) == 3) { 
    // scan valid... 
    cout << left << " " << o << " " << right; 
} 
0

Мой proposual заключается в создании в функции:

std::size_t delimiter_pos(const std::string line) 
{ 
    std::size_t found = std::string::npos; 
    (found = line.find('+')) != std::string::npos || 
    (found = line.find('-')) != std::string::npos || 
    (found = line.find('*')) != std::string::npos || 
    (found = line.find('/')) != std::string::npos; 
    return found; 
} 

И второй функц ион, вычислить операнды:

void parse(const std::string line) 
{ 
    std::string line; 
    std::size_t pos = delimiter_pos(line); 
    if (pos != std::string::npos) 
    { 
     std::string first = line.substr(0, pos); 
     char operation = line[pos]; 
     std::string second = line.substr(pos + 1, line.size() - (pos + 1)); 
    } 
} 

Я надеюсь, что мои примеры помогли вам

+0

Запускает проблемы со входом типа «1 * 2 + 3». Нахождение для '+' находит и возвращает 3, поэтому вызывающий элемент разделяет строку «1 * 2», «+», «3», что не совсем правильно. Тем не менее, вы очень близки. Просто продолжайте вызывать каждую строку до тех пор, пока не будет возвращено 'npos'. – user4581301

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