stringstream은 정확히 무엇을합니까? getline (cin,mystr);

저는 어제부터 C ++를 배우려고 노력하고 있으며이 문서를 사용하고 있습니다 : http://www.cplusplus.com/files/tutorial.pdf (page 32). 문서에서 코드를 찾아 실행했습니다. 가격은 Rs 5.5, 수량은 정수로 입력했는데 출력은 0이었습니다. 5.5와 6을 입력 해 보았는데 출력이 맞았습니다.

// stringstreams
#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

int main () 
{ 
  string mystr; 
  float price = 0; 
  int quantity = 0; 

  cout << "Enter price: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> price; 
  cout << "Enter quantity: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> quantity; 
  cout << "Total price: " << price*quantity << endl; 
  return 0; 
}

질문 : mystring 명령은 정확히 무엇을합니까? 문서에서 인용 :

“이 예에서는 표준 입력에서 간접적으로 숫자 값을 얻습니다. 표준 입력에서 직접 숫자 값을 추출하는 대신 표준 입력 (cin)에서 문자열 객체 (mystr)로 줄을 가져온 다음 정수를 추출합니다. 이 문자열의 값을 int (수량) 유형의 변수로 변환합니다. “

내 인상은 함수가 문자열의 필수 부분을 취하여 입력으로 사용한다는 것입니다.

(여기에서 질문하는 방법을 정확히 모르겠습니다. 저도 프로그래밍이 처음입니다.) 감사합니다.



답변

때때로 stringstream을 사용하여 문자열과 다른 숫자 유형간에 변환하는 것이 매우 편리합니다. 의 사용법은의 사용법과 stringstream유사 iostream하므로 배우는 데 부담이되지 않습니다.

Stringstreams는 문자열을 읽고 데이터를 문자열에 쓰는 데 사용할 수 있습니다. 주로 문자열 버퍼로 작동하지만 실제 I / O 채널은 없습니다.

stringstream 클래스의 기본 멤버 함수는 다음과 같습니다.

  • str(), 버퍼의 내용을 문자열 유형으로 반환합니다.

  • str(string), 버퍼의 내용을 문자열 인수로 설정합니다.

다음은 문자열 스트림을 사용하는 방법의 예입니다.

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

결과는 dec: 15 hex: f입니다.

istringstream 거의 동일하게 사용됩니다.

요약하면 stringstream은 독립적 인 I / O 장치처럼 문자열조작 하는 편리한 방법 입니다.

참고로, 클래스 간의 상속 관계는 다음과 같습니다.


답변

질문에 답하기 위해. stringstream기본적으로 string객체 를로 처리하고 stream모든 stream함수와 연산자를 사용할 수 있습니다.

주로 형식화 된 출력 / 입력의 장점에 사용되는 것을 보았습니다.

한 가지 좋은 예는 c++숫자를 스트림 객체로 변환하는 구현입니다.

가능한 예 :

template <class T>
string num2str(const T& num, unsigned int prec = 12) {
    string ret;
    stringstream ss;
    ios_base::fmtflags ff = ss.flags();
    ff |= ios_base::floatfield;
    ff |= ios_base::fixed;
    ss.flags(ff);
    ss.precision(prec);
    ss << num;
    ret = ss.str();
    return ret;
};

조금 복잡 할 수도 있지만 꽤 복잡합니다. stringstream객체를 만들고 ss, 플래그를 수정하고,로 숫자를 입력하고 operator<<,을 통해 추출합니다 str(). 나는 그것이 operator>>사용될 수 있다고 생각한다 .

또한이 예에서 string버퍼는 숨겨져 있으며 명시 적으로 사용되지 않습니다. 그러나 가능한 모든 측면과 사용 사례에 대해 작성하는 것은 너무 긴 게시물입니다.

참고 : 나는 아마 누군가에게서 그것을 훔쳐서 다듬었을 것입니다. 그러나 나는 원저자가 언급하지 않았습니다.


답변

에서 C ++ 프라이머 :

istringstream의 유형은 읽고 문자열을 , ostringstream이 기록 문자열을 , 그리고 이제 stringstream은 읽고 쓰는 문자열 .

stringstream 을 사용하는 것이 편리하고 간결한 경우가 있습니다 .

사례 1

그것은에서입니다 솔루션 중 하나 에 대한 이 leetcode 문제 . stringstream 의 사용 이 효율적이고 간결한 매우 적합한 경우를 보여줍니다 .

가정 ab문자열 형식으로 표현 복소수, 우리의 곱셈의 결과를 얻을 ab문자열 형식으로도. 코드는 다음과 같습니다.

string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;

int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of 
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;

out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';

// final result in string format
string result = out.str() 

사례 2

또한 주어진 경로 문자열을 단순화 해야하는 leetcode 문제 에서 비롯되었습니다. stringstream을 사용하는 솔루션 중 하나는 제가 본 것 중 가장 우아합니다.

string simplifyPath(string path) {
    string res, tmp;
    vector<string> stk;
    stringstream ss(path);
    while(getline(ss,tmp,'/')) {
        if (tmp == "" or tmp == ".") continue;
        if (tmp == ".." and !stk.empty()) stk.pop_back();
        else if (tmp != "..") stk.push_back(tmp);
    }
    for(auto str : stk) res += "/"+str;
    return res.empty() ? "/" : res;
 }

stringstream을 사용하지 않으면 이러한 간결한 코드를 작성하기 어려울 것입니다.


답변

영숫자 및 정수를 입력했으며 mystr.

그런 다음 첫 번째 토큰 (공백으로 구분)을 int.

첫 번째 토큰은로 변환에 실패한 RS int였으며 myprice에 0을 남겨 두었습니다. 우리는 모두 0 배가 무엇인지 알고 있습니다.

두 번째로 int 값만 입력하면 모든 것이 예상대로 작동했습니다.

코드를 실패하게 만든 것은 가짜 RS였습니다.