Можно ли принять от пользователя (стандартный ввод) прямой поток строк? - PullRequest
1 голос
/ 08 августа 2010

Вот пример программы, которая использует stringstream. Цель состоит в том, чтобы принять строки от пользователя (стандартный ввод) и напечатать каждое слово в отдельной строке.

int main()
{

    std::istringstream currentline;
    std::string eachword;
    std::string line;

    // Accept line from the standard input till EOF is reached
    while ( std::getline(std::cin,line) )
    {
        currentline.str(line); // Convert the input to stringstream
        while ( currentline >> eachword ) // Convert from the entire line to individual word
        {
            std::cout << eachword << std::endl;
        }
        currentline.clear();
    }
    return 0;
}

Мне интересно, есть ли способ, я могу избежать промежуточной строковой переменной (объекта), строки и напрямую сохранить пользовательский ввод в текущей строке (объект istringstream).

Примечание:

Я знаю, следующее решение уже.

while ( std::cin >> eachword)
{
    std::cout << eachword << std::endl;
}

Ответы [ 3 ]

1 голос
/ 08 августа 2010

std::getline нужен аргумент ссылки на строку, и именно туда он помещает полученную строку, поэтому, конечно, вы не можете избежать передачи такого аргумента (и все еще использовать эту функцию).Вы можете элегантно инкапсулировать конструкцию, если вам это нужно часто, например:

bool getline(std::istream& i, std::istringstream& current)
{
    std::string line;
    if ( std::getline(i, line) ) {
        current.str(line);
        return true;
    }
    return false;
}
0 голосов
/ 08 августа 2010

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

Вы можете добиться того же эффекта, явно указав область буфера потоковых буферов.

int main()
{
    std::string line;
    std::istringstream currentline;
    std::string eachword;

    // Accept line from the standard input till EOF is reached
    while ( std::getline(std::cin,line) )
    {
        // Set the buffer without copying.
        currentline.clear();
        currentline.rdbuf()->pubsetbuf(&line[0], line.length() );

        while ( currentline >> eachword )
        {
            std::cout << eachword << std::endl;
        }
    }
    return 0;
}

Из-запорядок уничтожения.Вам просто нужно убедиться, что istringstream уничтожен, прежде чем объект, который вы используете в качестве буфера.Таким образом, вам нужно изменить порядок объявлений в верхней части main (), чтобы убедиться, что строка создается первой и, следовательно, будет уничтожена последней (в противном случае деструктор istringstream может получить доступ к памяти свободного объекта)..

0 голосов
/ 08 августа 2010

Если вы хотите упростить первое решение,

while ( currentline(line) >> eachword )
...