Попытка вставить неизвестное число строк в вектор, но мой цикл cin не завершается - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь взять строки как входные данные из cin, а затем каждый раз вставлять строку в вектор.Тем не менее, мой цикл не прерывается, даже когда я ставлю '\' в конце всего ввода.

int main(void) {
    string row;
    vector<string> log;
    while (cin >> row) {
        if (row == "\n") {
            break;
        }
        log.push_back(row);
    }
    return 0;
}

Я пытался заменить (cin >> row) на (getline(cin,row)), но это не имело никакого значения.Я пытался использовать stringstream, но я действительно не знаю, как это работает.Как мне решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Вы не можете читать новую строку, используя istream& operator >> строки.Этот оператор игнорирует пробелы и никогда не вернет строку "\n".Попробуйте вместо этого использовать getline .

0 голосов
/ 23 января 2019

Если вы хотите сохранить токены одной строки из std::cin, разделенные стандартным механизмом, как при перегрузках operator>> из <iostream> (т. Е. Разделенных пробелами / символами новой строки), Вы можете сделать это так:

std::string line;
std::getline(std::cin, line);
std::stringstream ss{line};

const std::vector<std::string> tokens{std::istream_iterator<std::string>{ss},
    std::istream_iterator<std::string>{}};

Обратите внимание, что это не самое эффективное решение, но оно должно работать должным образом: обработать только одну строку и использовать существующий механизм для разделения этой строки на отдельные std::string объекты.

0 голосов
/ 23 января 2019

Как прокомментировал @SidS, пробел отбрасывается. Таким образом, вы должны подумать о другой стратегии. Вместо этого вы можете проверить, является ли row пустым. Но это будет работать только с std::getline:

#include <vector>
#include <string>
#include <iostream>

int main() {
    std::string row;
    std::vector<std::string> log;
    while (std::getline(std::cin, row)) {
        if (row.empty()) {
            break;
        }
        log.push_back(row);
    }
    std::cout << "done\n";
}

OP, если вы хотите сохранить отдельные слова (а не целую строку), вы можете использовать regex, чтобы в одиночку вставить каждое из них в log после ввода:

#include <vector>
#include <string>
#include <iostream>
#include <regex>

int main() {
    const std::regex words_reg{ "[^\\s]+" };

    std::string row;
    std::vector<std::string> log;
    while (std::getline(std::cin, row)) {
        if (row.empty()) {
            break;
        }
        for (auto it = std::sregex_iterator(row.begin(), row.end(), words_reg); it != std::sregex_iterator(); ++it){
            log.push_back((*it)[0]);
        }
    }
    for (unsigned i = 0u; i < log.size(); ++i) {
        std::cout << "log[" << i << "] = " << log[i] << '\n';
    }
}

Пример выполнения:

hello you
a b c d e f g
18939823
@_@_@ /////

log[0] = hello
log[1] = you
log[2] = a
log[3] = b
log[4] = c
log[5] = d
log[6] = e
log[7] = f
log[8] = g
log[9] = 18939823
log[10] = @_@_@
log[11] = /////
...