2017-01-09 7 views
1

getline()으로 전화를 걸 수있는 방법이 있습니까? 입력이 없으면 차단하고 기다리지 마십시오.어떻게 입력을 차단하지 않고 getline을 사용할 수 있습니까?

나는 다음과 같은 코드가 있습니다

while(true){ 
    if(recv(sd, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) > 0) break; 
    getline(cin,send); 
} 

내가 입력을 기다리고 싶지,하지만 내가 sd 소켓에서 일부 데이터를 수신하면, 나는 데이터를 기다리고 중지하고 while를 종료합니다. 지금 제 코드는 getline()에 첫 번째 반복에만 붙어 있습니다. getline()을 평가하고 싶습니다. 입력이 없으면 if으로 돌아갑니다.

이것이 가능합니까?

추신 : 나는 cin.peek()으로 시도했지만 그 입력을 차단했습니다.

+1

질문에 대답하려면 : 예, 가능합니다. 적어도 리눅스에서. –

+0

우분투를 사용하고 있습니다. 어떻게 가능합니까? 링크를 주거나 나에게 설명해 주시겠습니까? – Darius

+1

짧은 대답은 : 1) getline이 아닌 저수준 I/O를 사용하십시오. 2)'선택 '을 사용하십시오. –

답변

3

당신은 표준 입력에 비 차단 모드, 파일 기술자 0을 설정하여이 작업을 수행 할 수 있어야한다 : 어떤 입력을 사용할 수있을 경우, 기본 read() 시스템 호출은 0을 반환합니다

int flags = fcntl(0, F_GETFL, 0); 
fcntl(0, F_SETFL, flags | O_NONBLOCK); 

이제와 std::cin은이 파일의 끝이라고 생각하고 eof()std::cin에 설정합니다.

표준 입력에서 다시 읽으려는 경우 스트림의 상태는 clear()뿐입니다.

여기서 유일한 유일한 요소는 std::cin에서 실제 파일 끝 상태를 감지하기 어렵다는 것입니다. 표준 입력이 대화 형 터미널 인 경우별로 문제가되지 않습니다. 그러나 표준 입력이 파일 일 수 있다면 이것은 문제가 될 것입니다. 이 경우

는 유일한 현실적인 옵션은 완전히 std::cin을 포기 후 read(), 그것을 읽을 수있는 뭔가있을 때 결정하는 파일 기술자 0, poll() 또는 select()이에 비 차단 모드를 넣어하는 것입니다.

즉, 분명히, 어떤 종류의 선점 때문에 당신은 이미 std::cinstreambuf에 버퍼링 아무것도가 있다면 명시 적으로 확인해야하기 때문에 당신은 또한, poll() 또는 std::cinselect(), 이것은 복잡 것입니다 사용할 수 있지만 poll() 또는 select() 확인; 그러나 std::cin에서 무언가를 읽으려고하면 여전히 버퍼링 된 데이터를 읽은 다음 기본 파일 설명자인 read()을 비 차단 모드로 만들려고합니다. 이로 인해 가짜 EOF가 발생합니다.

요약 : 파일 스트림 및 스트림 버퍼 작동 방식을 읽고 추가로 이해해야합니다. 파일 설명자가 실제로 어떻게 작동하는지, 그리고 비 차단 모드가 작동하는 방법 올바른 논리를 이해하려면 사용해야합니다. 당신이 std::cin과 비 차단 경로를가는 주장하고 getline() 경우

아, 그리고, 당신은 getline() 실제로 표준 입력에서 개행 문자를 읽을 수 있기 때문에 getline()에 의해 반환 된 문자열이 끝나는 경우 쉽게 판별 할 방법이 없다, 또는 것 파일 조건의 조기 가짜 파일에 도달했으며 입력 전체가 실제로 읽히지 않았습니다.

따라서 비 차단 모드 및 std::cin 인 경우 getline() 대신 read()을 사용해야합니다.