Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
121 views
in Technique[技术] by (71.8m points)

Readin a line from console c++

I am new to c++ and I am a bit lost here!

I am trying to read the following line

* - 6 + x -6 - - 9 6 * 0 c

and I am iterating through the characters using

    for (std::string line; std::getline(std::cin, line);) {
        for(auto c : line){
          if(c != ' ')
        }
    }

now I am expecting to get "-6" at the sixth iteration but a I am getting "-" and then at the next iteration I am getting 6, I need to get "-6"! any help!

question from:https://stackoverflow.com/questions/65836080/readin-a-line-from-console-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the outer for loop, you are infinitely looping until getline() evaluates to false. In the inner for loop, you are looping through each character in line.

I don't know of any elegant syntax to parse a string into tokens like it seems you are trying to do. One way is to utilise std::stringstream and put things into an array or vector. Below is a sample main I wrote demonstrating how versatile this is:

#include <iostream>
#include <sstream>
#include <vector>

int main() {
    
    std::string line;
    while ( true ) {
        std::cout << "Enter parse string: ";
        std::getline( std::cin, line );
        
        if ( line == "Stop" ) break;        // Enter stop to quit program
        
        std::stringstream ss( line );       // constructor sets 'line' as contents of the stream
        std::vector <std::string> tokens;   // where our tokenised input is stored
        std::string temp;                   // where current token is temporarily loaded before it's put into the vector
        
        while( getline( ss, temp, ' ' ) )   // extract characters from ss until a space is found and stores them in temp
            tokens.push_back( temp );       // put the token formed by getline in our vector, from back so order is kept
        
        /*
         
          Now you can use the vector as you would like. Below the contents are printed.
        
         */
        
        for ( auto& x : tokens )            // for each token in 'tokens' vector,
            std::cout << x << ' ';          // print out token with a space at the end
    
        std::cout << "

";
        
        for ( int i = 0; i < tokens.size(); i++ )           // for each token in 'tokens' vector,
            std::cout << i << ": " << tokens[i] << '
';    // print out index number and token
        
        std::cout << std::endl;             // newline & flush
    }
    
    return 0;
}

If you want to abstract the details away, you could always wrap the std::stringstream stuff into a function that takes in a string and returns a std::vector<std::string>. Below I demonstrate what that would look like:

#include <iostream>
#include <sstream>
#include <vector>

std::vector <std::string> toParsedVector( std::string input ) {
    
    std::stringstream ss( input );      // constructor sets 'line' as contents of the stream
    std::vector <std::string> tokens;   // where our tokenised input is stored
    std::string temp;                   // where current token is temporarily loaded before it's put into the vector
    
    while( getline( ss, temp, ' ' ) )   // extract characters from ss until a space is found and stores them in temp
        tokens.push_back( temp );       // put the token formed by getline in our vector, from back so order is kept

    return tokens;
}

int main() {
    
    std::string line;
    while ( true ) {
        std::cout << "Enter parse string: ";
        std::getline( std::cin, line );
        
        if ( line == "Stop" ) break;        // Enter stop to quit program
        
        std::vector <std::string> tokens = toParsedVector( line ); // create vector
        
        // Now you can use the vector (tokens) as you would like. Below the contents are printed.
        
        for ( auto& x : tokens )            // for each token in 'tokens' vector,
            std::cout << x << ' ';          // print out token with a space at the end
    
        std::cout << "

";
        
        for ( int i = 0; i < tokens.size(); i++ )           // for each token in 'tokens' vector,
            std::cout << i << ": " << tokens[i] << '
';    // print out index number and token
        
        std::cout << std::endl;             // newline & flush
    }
    
    return 0;
}

I hope this helps; might not be the most elegant solution, but it is very versatile.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...