Trying to push an unknown number of strings into a vector, but my cin loop doesn't terminate












6















I am trying to take strings as input from cin, and then push the string into a vector each time. However, my loop doesn't terminate even when I put a '' at the end of all my input.



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


I've tried replacing the (cin >> row) with (getline(cin,row)), but it didn't make any difference. I've tried using stringstream, but I don't really know how it works. How do I go about resolving this?










share|improve this question




















  • 5





    cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

    – Sid S
    1 hour ago













  • Also consider breaking on row.empty().

    – Sid S
    1 hour ago
















6















I am trying to take strings as input from cin, and then push the string into a vector each time. However, my loop doesn't terminate even when I put a '' at the end of all my input.



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


I've tried replacing the (cin >> row) with (getline(cin,row)), but it didn't make any difference. I've tried using stringstream, but I don't really know how it works. How do I go about resolving this?










share|improve this question




















  • 5





    cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

    – Sid S
    1 hour ago













  • Also consider breaking on row.empty().

    – Sid S
    1 hour ago














6












6








6








I am trying to take strings as input from cin, and then push the string into a vector each time. However, my loop doesn't terminate even when I put a '' at the end of all my input.



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


I've tried replacing the (cin >> row) with (getline(cin,row)), but it didn't make any difference. I've tried using stringstream, but I don't really know how it works. How do I go about resolving this?










share|improve this question
















I am trying to take strings as input from cin, and then push the string into a vector each time. However, my loop doesn't terminate even when I put a '' at the end of all my input.



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


I've tried replacing the (cin >> row) with (getline(cin,row)), but it didn't make any difference. I've tried using stringstream, but I don't really know how it works. How do I go about resolving this?







c++ cin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago









Ivaylo Strandjev

56.4k1085142




56.4k1085142










asked 1 hour ago









cluelessguycluelessguy

311




311








  • 5





    cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

    – Sid S
    1 hour ago













  • Also consider breaking on row.empty().

    – Sid S
    1 hour ago














  • 5





    cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

    – Sid S
    1 hour ago













  • Also consider breaking on row.empty().

    – Sid S
    1 hour ago








5




5





cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

– Sid S
1 hour ago







cin >> row discards whitespace, so row is never going to be "n". If you want to end on , break on row == "\".

– Sid S
1 hour ago















Also consider breaking on row.empty().

– Sid S
1 hour ago





Also consider breaking on row.empty().

– Sid S
1 hour ago












3 Answers
3






active

oldest

votes


















5














As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
You could instead check if row is empty. But that will only work with 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 << "donen";
}




OP, in case you want to save single words (rather than a whole line), you can use regex to single-handedly push each of them into row after input:



#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';
}
}


Example run:



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] = /////





share|improve this answer


























  • Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

    – lubgr
    1 hour ago













  • @lubgr yeah you're right, I will add some regex for the curious, too

    – Stack Danny
    1 hour ago











  • @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

    – Ivaylo Strandjev
    1 hour ago













  • Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

    – Bob__
    1 min ago



















1














You can't read newline by using the istream& operator >> of string. This operator ignores whitespaces and will never return the string "n". Consider using getline instead.






share|improve this answer
























  • getline() won't return "n" either.

    – Sid S
    1 hour ago











  • No, it will not but it will serve the purpose to read a whole row.

    – Ivaylo Strandjev
    1 hour ago



















1














If you want to store the tokens of one line from std::cin, separated by the standard mechanism as in the operator>> overloads from <iostream> (i.e., split by whitespace/newline), you can do it like this:



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>{}};


Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string objects.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54322351%2ftrying-to-push-an-unknown-number-of-strings-into-a-vector-but-my-cin-loop-doesn%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
    You could instead check if row is empty. But that will only work with 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 << "donen";
    }




    OP, in case you want to save single words (rather than a whole line), you can use regex to single-handedly push each of them into row after input:



    #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';
    }
    }


    Example run:



    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] = /////





    share|improve this answer


























    • Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

      – lubgr
      1 hour ago













    • @lubgr yeah you're right, I will add some regex for the curious, too

      – Stack Danny
      1 hour ago











    • @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

      – Ivaylo Strandjev
      1 hour ago













    • Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

      – Bob__
      1 min ago
















    5














    As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
    You could instead check if row is empty. But that will only work with 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 << "donen";
    }




    OP, in case you want to save single words (rather than a whole line), you can use regex to single-handedly push each of them into row after input:



    #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';
    }
    }


    Example run:



    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] = /////





    share|improve this answer


























    • Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

      – lubgr
      1 hour ago













    • @lubgr yeah you're right, I will add some regex for the curious, too

      – Stack Danny
      1 hour ago











    • @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

      – Ivaylo Strandjev
      1 hour ago













    • Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

      – Bob__
      1 min ago














    5












    5








    5







    As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
    You could instead check if row is empty. But that will only work with 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 << "donen";
    }




    OP, in case you want to save single words (rather than a whole line), you can use regex to single-handedly push each of them into row after input:



    #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';
    }
    }


    Example run:



    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] = /////





    share|improve this answer















    As commented by @SidS, the whitespace is discarded. So you have to think about another strategy.
    You could instead check if row is empty. But that will only work with 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 << "donen";
    }




    OP, in case you want to save single words (rather than a whole line), you can use regex to single-handedly push each of them into row after input:



    #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';
    }
    }


    Example run:



    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] = /////






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited just now

























    answered 1 hour ago









    Stack DannyStack Danny

    1,206320




    1,206320













    • Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

      – lubgr
      1 hour ago













    • @lubgr yeah you're right, I will add some regex for the curious, too

      – Stack Danny
      1 hour ago











    • @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

      – Ivaylo Strandjev
      1 hour ago













    • Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

      – Bob__
      1 min ago



















    • Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

      – lubgr
      1 hour ago













    • @lubgr yeah you're right, I will add some regex for the curious, too

      – Stack Danny
      1 hour ago











    • @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

      – Ivaylo Strandjev
      1 hour ago













    • Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

      – Bob__
      1 min ago

















    Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

    – lubgr
    1 hour ago







    Isn't the OP's original goal to store an individual token as a std::string in the container, rather than each line? There should be an additional step to split each row according to a given delimiter.

    – lubgr
    1 hour ago















    @lubgr yeah you're right, I will add some regex for the curious, too

    – Stack Danny
    1 hour ago





    @lubgr yeah you're right, I will add some regex for the curious, too

    – Stack Danny
    1 hour ago













    @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

    – Ivaylo Strandjev
    1 hour ago







    @lubgr in fact I am not certain what is the original intent of the OP, as the variable name is row I think storing the whole line is more plausible

    – Ivaylo Strandjev
    1 hour ago















    Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

    – Bob__
    1 min ago





    Have you considered using while (std::getline(std::cin,row)) {…} to break the loop in case of input failures?

    – Bob__
    1 min ago













    1














    You can't read newline by using the istream& operator >> of string. This operator ignores whitespaces and will never return the string "n". Consider using getline instead.






    share|improve this answer
























    • getline() won't return "n" either.

      – Sid S
      1 hour ago











    • No, it will not but it will serve the purpose to read a whole row.

      – Ivaylo Strandjev
      1 hour ago
















    1














    You can't read newline by using the istream& operator >> of string. This operator ignores whitespaces and will never return the string "n". Consider using getline instead.






    share|improve this answer
























    • getline() won't return "n" either.

      – Sid S
      1 hour ago











    • No, it will not but it will serve the purpose to read a whole row.

      – Ivaylo Strandjev
      1 hour ago














    1












    1








    1







    You can't read newline by using the istream& operator >> of string. This operator ignores whitespaces and will never return the string "n". Consider using getline instead.






    share|improve this answer













    You can't read newline by using the istream& operator >> of string. This operator ignores whitespaces and will never return the string "n". Consider using getline instead.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 1 hour ago









    Ivaylo StrandjevIvaylo Strandjev

    56.4k1085142




    56.4k1085142













    • getline() won't return "n" either.

      – Sid S
      1 hour ago











    • No, it will not but it will serve the purpose to read a whole row.

      – Ivaylo Strandjev
      1 hour ago



















    • getline() won't return "n" either.

      – Sid S
      1 hour ago











    • No, it will not but it will serve the purpose to read a whole row.

      – Ivaylo Strandjev
      1 hour ago

















    getline() won't return "n" either.

    – Sid S
    1 hour ago





    getline() won't return "n" either.

    – Sid S
    1 hour ago













    No, it will not but it will serve the purpose to read a whole row.

    – Ivaylo Strandjev
    1 hour ago





    No, it will not but it will serve the purpose to read a whole row.

    – Ivaylo Strandjev
    1 hour ago











    1














    If you want to store the tokens of one line from std::cin, separated by the standard mechanism as in the operator>> overloads from <iostream> (i.e., split by whitespace/newline), you can do it like this:



    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>{}};


    Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string objects.






    share|improve this answer






























      1














      If you want to store the tokens of one line from std::cin, separated by the standard mechanism as in the operator>> overloads from <iostream> (i.e., split by whitespace/newline), you can do it like this:



      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>{}};


      Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string objects.






      share|improve this answer




























        1












        1








        1







        If you want to store the tokens of one line from std::cin, separated by the standard mechanism as in the operator>> overloads from <iostream> (i.e., split by whitespace/newline), you can do it like this:



        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>{}};


        Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string objects.






        share|improve this answer















        If you want to store the tokens of one line from std::cin, separated by the standard mechanism as in the operator>> overloads from <iostream> (i.e., split by whitespace/newline), you can do it like this:



        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>{}};


        Note that this is not the most efficient solution, but it should work as expected: process only one line and use an existing mechanism to split this line into individual std::string objects.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 17 mins ago

























        answered 1 hour ago









        lubgrlubgr

        10.6k21745




        10.6k21745






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54322351%2ftrying-to-push-an-unknown-number-of-strings-into-a-vector-but-my-cin-loop-doesn%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            SQL Server 17 - Attemping to backup to remote NAS but Access is denied

            Always On Availability groups resolving state after failover - Remote harden of transaction...

            Restoring from pg_dump with foreign key constraints