Zajímavosti z C++: Načtení celého vstupu do std::string v jednom příkazu

Od Petr Zemek, 2010-03-27

Včera jsem s kamarádem řešil, zda a jak lze v C++ načíst celý obsah vstupu do std::string v jediném příkazu. Pokud by to někoho zajímalo, tak odpověď dává následující krátký příspěvek.

Řešení

Ano, je to možné, a to následovně:

#include <iostream>
#include <iterator>
#include <string>
 
using namespace std;
 
int main() {
    string s((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
}

Je použit dvouparametrový konstruktor string(input_iterator start, input_iterator end), kde start je iterátor ukazující na začátek vstupu a end je iterátor ukazující těsně za konec vstupu (já vím, zní to zajímavě, že u vstupu, u kterého nevíte, jak bude dlouhý, vytváříte iterátor ukazující za jeho konec :)). Jsou použity iterátory istreambuf_iterator<char>, které postupují znak po znaku, a to nezávisle na jeho hodnotě (viz dále). Jelikož chceme číst ze vstupu, tak prvnímu iterátoru předáme standardní proud cin. Volání istreambuf_iterator<char>() nám vytvoří onen iterátor ukazující znak za konec vstupu.

Na co si dát pozor

Je třeba si dát pozor na dvě věci. Za prvé, nelze použít iterátor istream_iterator, protože ten by způsobil, že by došlo k zahození všech bílých znaků ze vstupu (což ve většině případů nechcete).

string s((istream_iterator<char>(cin)), istream_iterator<char>()); // Zahodí bílé znaky na vstupu

Za druhé, zdánlivě nadbytečné závorky jsou opravdu nutné, jinak bychom místo objektu typu string deklarovali funkci (zájemce o bližší vysvětlení odkazuji zde). Schválně si můžete zkusit přeložit následující kód:

string s(istreambuf_iterator<char>(cin), istreambuf_iterator<char>()); // Deklarace funkce!

Pokud bychom nepoužili direktivu/deklaraci using a kvalifikovali bychom istreambuf_iterator jmenným prostorem std:: explicitně, problém by nenastal (jména formálních parametrů funkcí nemohou mít v názvu dvojtečky).

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
2 + 16 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.