Fill vector with input from cin without loop



  • // implying std::vector<Foo> vec; ...
    std::copy(std::istream_iterator<Foo>(std::cin), std::istream_iterator<Foo>(), std::back_inserter(vec));
    


  • ach ja, vergiss meinen Code, die Variante mit std::back_inserter ist natürlich die richtige...



  • dot schrieb:

    ach ja, vergiss meinen Code, die Variante mit std::back_inserter ist natürlich die richtige...

    Ich find deine aber eleganter. Und die ist kürzer.



  • Nathan schrieb:

    dot schrieb:

    ach ja, vergiss meinen Code, die Variante mit std::back_inserter ist natürlich die richtige...

    Ich find deine aber eleganter. Und die ist kürzer.

    Hach, ich bin noch etwas...unausgeschlafen 🤡 ...dachte für einen Moment, dass bei mir der vector sich doch nicht passend vergrößern würde und man darum den back_inserter benötigt, tut er ja aber eh...



  • Nathan schrieb:

    dot schrieb:

    ach ja, vergiss meinen Code, die Variante mit std::back_inserter ist natürlich die richtige...

    Ich find deine aber eleganter. Und die ist kürzer.

    vec.insert(end(vec), istream_iterator<Foo>(cin), istream_iterator<Foo>());
    copy(istream_iterator<Foo>(cin), istream_iterator<Foo>(), back_inserter(vec));
    
    std::copy(std::istream_iterator<Foo>(std::cin), std::istream_iterator<Foo>(), std::back_inserter(vec));
    vec.insert(std::end(vec), std::istream_iterator<Foo>(std::cin), std::istream_iterator<Foo>());
    

    Nur geringfügig, und insert erweckt den Eindruck, dass man irgendwo innerhalb des Vector einfügen will, dementsprechend ist copy da was aussagekräftiger. Aber jeder wie er mag 🙂



  • Supi beide Lösungen funktionieren, danke.

    Gibt es einen einfachen Trick, damit es ähnlich wie hier nur das Drücken der Enter taste bedarf, damit die Eingabe aufhört und nicht einen nicht-int, z.B. ';'.

    string str;
    getline(cin, str);
    stringstream stream(str);
    int temp;
    while (stream >> temp)
        vec.push_back(temp);
    

    Wenn nicht, ist es auch kein großes Thema, ist trotzdem einfacher meiner Meinung nach.


  • Mod

    Warum hat noch keiner die deutlich kürzere Variante gezeigt?

    vec.insert(vec.end(), istream_iterator<Foo>(cin), {});
    


  • Arcoth schrieb:

    Warum hat noch keiner die deutlich kürzere Variante gezeigt?

    vec.insert(vec.end(), istream_iterator<Foo>(cin), {});
    

    oder noch kürzer

    vec.insert(end(vec), istream_iterator<bla>(cin), {});
    

    :p


  • Mod

    Gibt es einen einfachen Trick, damit es ähnlich wie hier nur das Drücken der Enter taste bedarf, damit die Eingabe aufhört und nicht einen nicht-int, z.B. ';'.

    Es gibt einen sexy Trick.

    class newline_sep : public std::ctype<char>
    {
    	mask const* create_table()
    	{
    		static mask table[table_size];
    		if (table[std::size_t(' ')] == 0)
    		{
    			std::copy_n( classic_table(), table_size, table );
    			table[std::size_t('\n')] &= ~space;
    		}
    
    		return table;
    	}
    
    public:
    
    	newline_sep(std::size_t refs = 0) : ctype(create_table(), false, refs) {}
    };
    

    Dann in cin imbuen:

    cin.imbue( locale(cin.getloc(), new newline_sep) );
    

    Und voila:

    vector<int> v( istream_iterator<int>(cin), {} );
    
    	for (auto i : v)
    		std::cout << i << ", ";
    

    Sollte bei Zeilengesteuerten Konsolen beim drücken der Enter-Taste abbrechen.

    Ich kann mich im Übrigen erinnern diese MEthode in irgendeinem cppreference Beispiel gesehen zu haben. Kann das jemand rauskramen?
    Edit: Ich bin wohl blind, das ist ja das Beispiel von ctype<char> selbst. Hab' den Code angepasst.



  • wow... fragt sich, ob der comfort auch gut ist, wenn ich den Trick absolut nicht verstehe, oder ob es dann doch sinnvoller ist, einfach ein ';' etc. einzugeben 😃



  • HarteWare schrieb:

    wow... fragt sich, ob der comfort auch gut ist, wenn ich den Trick absolut nicht verstehe, oder ob es dann doch sinnvoller ist, einfach ein ';' etc. einzugeben 😃

    Simulier EOF: Strg+Z (Win), Strg+D (Linux)
    Ist "sauberer" als Müll einzugeben und funktioniert auch bei Strings.



  • Arcoth schrieb:

    Warum hat noch keiner die deutlich kürzere Variante gezeigt?

    vec.insert(vec.end(), istream_iterator<Foo>(cin), {});
    

    Weil Visual Studio das noch nicht ausreichend gut unterstützt als dass ich es nutze und mich daran gewöhnt hab 😃



  • Gibts es überhaupt nen guten Grund nicht einfach die erste Variante zu nehmen (mit move)? 🤡



  • cooky451 schrieb:

    Gibts es überhaupt nen guten Grund nicht einfach die erste Variante zu nehmen (mit move)? 🤡

    Das wäre zu kurz, nicht ausreichend kryptisch genug und man müsste <iterator> nicht includen.


Anmelden zum Antworten