2010-03-06 3 views
1

입력 문자열에서 숫자와 문자를 구분하는 데 문제가 있습니다. 내 프로그램의 목적은 +는 2 2 3 + * (답되는 10)2에서 아무것도 할 수 그래서 난 입력 양식을 예측하지 못할 더하기, 빼기, 곱하기 및 후위에 분할하는 것입니다 3 * (대답 12). 그래서 sscanf를 사용하여 입력 문자열에 특정 형식을 사용하지 않고 번호와 연산자 문자를 추출 할 수 있습니다. 내가 여기서 뭘해야하지?특정 형식을 따르지 않는 문자열에서 숫자와 문자를 추출 하시겠습니까? (후위 계산기)

+1

이 숙제가 있습니까? 귀하가 "가져 오기, 다음으로 변환해야합니다."라는 귀하의 의견은 그렇게 나타납니다. – Vatine

+0

예, 나는이 단계에 머물러 있습니다. – silent

+0

태그가 지정된 숙제. – Tronic

답변

2

글쎄, 당신은 그래서 당신은 스택을 구현하려는거야 접미사를 처리 할 수 스택에 각 숫자를 가져와야합니다. 각 연산자는 스택에서 두 개 팝하고 결과를 다시 푸시합니다.

+0

스택을 사용하고 있지만 입력을 사용하려면 get을 사용하고 스택으로 숫자를 변환하고 푸시해야합니다. – silent

+0

숫자 또는 연산자인지를 감지하는 데 isalpha()를 사용하지 않는 이유는 무엇입니까? – uray

+1

필수 가져 오기를 사용 하시겠습니까? 이 기능이 설계 상 부러 졌다고 교사에게 이야기하십시오. 매뉴얼 페이지에 - gets()를 사용하지 말라. 얼마나 많은 문자 gets()가 읽을지 미리 알 수 없기 때문에 gets()는 버퍼의 끝까지 문자를 계속 저장하기 때문에 사용하는 것은 매우 위험합니다. 그것은 컴퓨터 보안을 깨는 데 사용되었습니다. 대신 fgets()를 사용하십시오. – Tronic

0

정말 좋은 파서 라이브러리 인 Boost.Spirit Qi를 사용하는 것이 좋습니다. 첫 번째 예는 ... 계산기입니다

http://www.boost.org/doc/libs/1_42_0/libs/spirit/doc/html/spirit/introduction.html

표준 라이브러리 유일한 해결책 :

// Get a line of user input (simplifies I/O) 
std::string line; 
if (!std::getline(std::cin, line)) throw std::runtime_error("Unable to read line"); 
// Process the line as an input string stream 
std::istringstream iss(line); 
while (true) { 
    unsigned int val; 
    if (iss >> val) { 
     // TODO: Handle a numeric value (in val) 
     continue; 
    } 
    iss.clear(); // Clear the error state 
    char ch; 
    if (!iss.get(ch)) break; // Break the loop if there is no more input 
    // TODO: Handle a character (in ch) 
} 
+0

stdlib 솔루션으로 업데이트되었습니다. 숙제를 위해서는 – Tronic

+0

을 사용해야합니다. 도서관 대신에 기본을 고수하는 것이 좋습니다. – NomeN

2

한 가지 방법은 다음 공백까지 문자를 반환하는 scanf("%s")을 사용하는 것입니다. 또는 getc을 사용하여 한 번에 하나씩 문자를 가져올 수 있습니다.

편집 : 나는 당신이이 경우에, 전체 라인에 읽어 얻는 사용하고 의견에서 볼

, 당신은 토큰들로 라인을 중단하고보고 루프에서 strtok를 사용하여 더 나을 수 있습니다 각 토큰의 첫 번째 문자로 무엇을해야할지 결정합니다.

char line[MAX_LINE]; 
// read in the line 

char * pTok = strtok(line, " \t"); 
while (pTok) 
{ 
    char ch = pTok[0]; 
    if (isdigit(ch)) 
     //handle number 

    if (ch == '+') 
     //handle addition operator 

    ... 
    pTok = strtok(NULL, " \t"); 
} 
+0

그는 C++을 사용하고 있으므로 동등한 기능은 std :: cin >> val (공백을 무시하고 숫자를 읽으려고합니다) 및 std :: cin.clear(); 숫자를 읽은 후 std :: cin.get (ch)가 실패합니다. – Tronic

+0

@ 트로닉 : 그는 sscanf를 언급 한 사람이었습니다. std ::를 사용하려면 C++ 코드가 _required_가 아닙니다. –

+0

scanf를 사용할 수 있지만 계산되는 숫자의 양은 가변적입니다. – silent

0

전체 줄을 가져 와서 문자열, 오프셋 및 반환 구조체를 사용하는 함수를 사용하면됩니다. 반환 구조체에는 토큰의 시작 및 끝 오프셋, 토큰 유형 (연산자, 인수) 및 가능한 다른 것들이 포함됩니다.

또는 숫자를 확인하는 함수와 연산자를 확인하는 함수의 두 가지 함수로 나눕니다.