2012-11-25 4 views
1

저는 3 개월 동안이 작업을 수행했으며 현재는 여전히 대기 상태입니다. 나는 내가 뭘 잘못하고 있는지 확신하지 못한다. 나는 올바른 방향으로 나를 가리키는 도움을 주시면 감사하겠습니다. 나는 누군가 나를 위해 숙제를하라고 요구하지 않는다. 나는 한 줄의 입력을 받아들이고 소문자 수를 세고 출력하는 프로그램을 작성해야한다. 이것은 내가 지금까지 가지고있는 일이지만 그것이해야 할 일을하지 않습니다.C++ 사용자가 입력 한 텍스트 줄의 소문자 수를 계산합니다.

#include <fstream> 
#include <iostream> 
#include <cctype> 
#include <string> 

using namespace std; 

int main(){ 
    char text; 
    int count = 0; 
    cout << " Enter one line of text: "; 

    do 
    { 
     cin.get(text); 

     while(text!='\n') 
     { 
      if(islower(text)) 
      count++; 
     } 
    } while(text!='\n'); 

    cout << count << "\n"; 
} 
+0

그래서 * *이 무엇을합니까? 마치 무한 루프에 갇히게 될 것 같은데 ...? – MadSkunk

답변

2

당신은 무한 루프를 만듭니다

while (text != '\n') { 
    ... 
} 

영원히 경우 text (다소 문자에 대한 잘못된 이름의) 계속 적 '\ n을'다른 무언가로 발생합니다. 일반적인 지침으로, 루프를 만들 때마다 루프 본문이 어떻게 든 루프의 끝으로 진행하고 루프의 끝 부분에 도달했는지 확인해야합니다 (물론 무한대를 만들지 않는 한) lop) 아마도 이걸 없애고 그냥 while (...)의 몸을 지키고 싶을 것입니다. 외부 루프는 두 가지 조건이 있어야합니다

참고 종료하기 : 당신이 라인의 끝에 도달하면

  1. 이 종료해야합니다.
  2. 입력의 끝 부분에 도달하면 종료되어야합니다. 이것은 반드시 개행으로 종료되지는 않습니다. 내가 루프를 작성한다면

는 다음과 같이 보일 것입니다 :

for (std::istreambuf_iterator<char> it(std::cin), end; it != end && *it != '\n'; ++it) { 
    // do something with the `char` obtained from `*it` 
} 

을 그것은 또한 당신이 양의 값이 islower()에 전달되어 있는지 확인해야한다는 것을 주목할 필요가있다 (또는 어떤 <cctype>의 다른 기능) : char에 서명 된 시스템이 있습니다. 예를 들어 내 이름에 ü이 음수 값으로 변환되어 islower('ü')을 호출 할 때 정의되지 않은 동작을 일으키는 시스템이 있습니다. 이 문제를 피하는 방법은 <cctype> 함수에 전달하기 전에 unsigned char으로 변환하는 것입니다. static_cast<unsigned char>(c)의 비트 패턴은 c의 비트 패턴 (char이라고 가정)과 동일합니다. char을 읽는 while -loop의 원래의 접근 방식을 고집

, 기본 루프 같은 것을 보일 것이다 : 일반적으로

while (std::cin.get(text) && text != '\n') { 
    if (std::islower(std::static_cast<unsigned char>(text))) { 
     ++count; 
    } 
} 

을, 나는 do ... while -loops 거의으로 살아남을하지 않는 것을 발견했다 프로덕션 코드이며 이것은 예외는 아닙니다. char을 성공적으로 읽을 수있는 경우에만 루프에 들어가기를 원합니다. 개행 문자는 소문자가 아니기 때문에 직접 입력 할 수도 있습니다. ASCII 문자 std::islower(text)의 경우 코드가 제대로 작동하도록 작동하지만 코드를 unsigned char에 추가하여 문제가 발생하지 않도록합니다. 마지막으로, 변수를 증가시키는 C++ 관용구는 역설적으로 사전 증가, 즉 count++ 대신에 ++count입니다. 기본 사용법은 적용되는 유형이 완전히 사소하지 않은 경우 사전 증가가 더 효율적이라는 것입니다. C++에서는 증가하는 반복자를 많이 사용하기 때문에 사전 증가를 사용하는 것이 일반적입니다.

+0

매우 완전한 대답을위한 +1 – sehe

3

입력에 문제가있었습니다. 별개의 문자를 입력했지만 공백은 건너 뜁니다.

당신은 한 번에 입력 라인을 얻을 수 std::getline를 사용할 수 있습니다

#include <algorithm> 
#include <iostream> 
#include <cctype> 
#include <string> 

using namespace std; 

int main() 
{ 
    cout << " Enter one line of text: "; 
    string s; 
    if(getline(cin, s)) 
    { 
     size_t count = count_if(s.begin(), s.end(), 
       [](unsigned char ch) { return islower(ch); }); 
     cout << count << "\n"; 
    } 
} 
+0

질문의 이전 인스턴스에 [내 대답] (http://stackoverflow.com/a/13545371/1120273)과 다소 유사하게 보이는 점을 제외하고는 내 대답에'std :: char'가 서명 된 경우,'islower()'의'int' 인수가 양수 여야하기 때문에 정의되지 않은 동작을 생성 할 것입니다. 즉,'char'를'unsigned char'로 변환하고 이것을'int'로 승격시켜야합니다. 코드에서 이것을하는 가장 쉬운 방법은 람다가'unsigned char'를 취하도록 정의하는 것입니다. ' '함수의 잘못된 사용은 내 애완 동물의 오줌 중 하나입니다. –

+0

'size_t '는'sizeof()'표현식의 결과에 사용되는 타입입니다. 즉,'count'는 부호없는 정수 타입으로 선언됩니다. 그 값은'std :: count_if()'알고리듬의 결과로 초기화된다. 이 알고리즘은's.begin()'에서 시작하여's.end()'에서 끝나는 문자의 순서로 호출됩니다. 즉, 알고리즘은's'의 문자 시퀀스로 호출됩니다. 'std :: count_of()'의 마지막 인수는'islower()'를 호출하는 lambda 표현식입니다. sehe _could_는'static_cast (std :: islower)'를 대신 사용했습니다. –

+0

물론 sehe는 아마도 [] (unsigned char c) {return islower (c); }'를 호출하여'unsigned char '에'char'을 던져서'islower()'를 올바르게 호출합니다. 람다 표현식은 _capture_ (이 경우'[]')로 시작하여 참조 된 변수가 어떻게 처리되는지를 나열합니다 (이 경우에는 참조 된 변수가 없습니다). 다음은 함수 인수 목록 (이 경우 선택적이지만 현재 있음)이옵니다. 단 하나의'return' 문이 있기 때문에'return' 유형은 추론 될 수 있고 생략 될 수 있습니다. 마지막으로 함수 본문이 있습니다. C++ 2011에서만 작동합니다. –

관련 문제