2016-07-30 5 views
0

나는 사용자 정의 헤더 파일이 프로젝트를 만드는 작업을하고, 실행하고있다 :문제 몇 가지 문제에

이 코드에 정확히 무슨 일이 있었는지 모르겠지만, 후 내가 fgets() 함수를 사용하기 시작했다면, 그것은 내 코드에서 일부 printf()의 출력을 멈춘 것으로 보인다. 여기에 아마 여기에 몇 가지 #include 문을 누락 코드의 중요한 부분은 다음과 같습니다

main.cpp

#include "ichat.h" 

int main() { 

    prompts(P_IDLE, response); 
    prompts(P_USERNAME, response); 
} 

ichat.cpp

#include "ichat.h" 
int prompts(int p_tag, char *response) { 

    if (p_tag == P_IDLE) { 

     printf("\nWaiting for connections. Press [ENTER] to start a chat."); 
     char msg[50]; 
     char *ptr; 
     while (true) { 

      fgets(msg, strlen(msg), stdin); 
      ptr = (char*)memchr(msg, '\n', strlen(msg)); 
      if (ptr != NULL) { 

       break; 
      } 

    } else if (p_tag == P_USERNAME) { 

     printf("\nPlease enter a username you'd like to use: "); 
     .... 

    } ... 

ichat.h의 일부, 당신이 궁금했다 까봐 ...

#define P_IDLE 0 
#define P_USERNAME 1 

gcc main.cpp ichat.cpp.

fgets() 함수로 while 루프를 추가 할 때 printf() 함수 중 아무 것도 출력을 생성하지 않습니다. 인쇄 기능이 정상적으로 작동하고 있기 때문에 여기에 무슨 일이 일어나고 있는지 정확하게 알 수는 없으며 때로는 \n을 제거하거나 다른 printf() 기능을 추가하기도합니다. 꽤 혼란 스럽네요 ...

사용자가 입력하는 좋은 방법이 있습니까? 나는 나의 코드의 어떤 부분에 대한 어떤 힌트, 비평, 아이디어에 대해서도 열려있다.

+0

"fgets() 함수를 구현했습니다"라고 썼습니다. 마치'fgets()'의 자신 만의 버전을 작성하는 것처럼 들리지만 코드는 그냥 호출하는 것처럼 보입니다. 문제를 명확히하기 위해 질문을 업데이트하십시오. –

+0

fgets에 전달할 때 strlen이 반환 할 것으로 예상되는 것은 무엇입니까? 왜 iostream 대신 printf와 fgets를 사용한다면이 C++에 태그를 붙이겠습니까? – kfsone

+0

'strlen()'은 문자열'msg'의 길이를 그 함수에 전달한다고 나는 생각한다. 'printf'와'fgets'를 사용하고 있었기 때문에 제가이 주제에 대해 읽었던 책과 일치했습니다. iostreams로 전환 할 수 있습니다. 도움이 될 것이라고 생각하십니까? – SuperContraptionGuy

답변

1

문제의 요점은

char msg[50]; 
/* no initialisation of data in msg */ 
fgets(msg, strlen(msg), stdin); 

msg가 초기화되지 않은되고, 그래서 그 안에있는 모든 문자의 값은 불확정 - 그들은 제로 보장되지 않습니다. 형식적으로 심지어 값을 액세스 (strlen()'\0'을 검색)하면 정의되지 않은 동작이 발생합니다.

strlen(msg)sizeof msg (항상 50의 값)으로 변경해야합니다.

fgets()은 입력에 따라 msg을 수정합니다. 그런 다음 strlen()을 결과에 사용할 수 있습니다.

또한 memchr()과 같은 함수의 결과에 (char *) 유형 변환을 사용하지 말고 void *을 반환하십시오. #include <string.h>을 잊어 버린 경우 C에서만 필요합니다. 오른쪽 헤더를 포함하는 것이 유형 변환보다 나은 해결책입니다. C 컴파일러가 실제로 C++ 컴파일러 인 경우 변환이 필요하지만 C++은 대체로 더 선호되는 대체 방법을 제공합니다 (유형 안전성 등).

+0

당신은 그 C++ 접근법 중 일부를 제공 할 수 있습니까? 가능한 경우이 코드를 향상시키는 방법을 알고 싶습니다. 귀하의 답변에 감사드립니다. – SuperContraptionGuy

+0

그것은 분명히 달성하려는 대상에 따라 다릅니다. 일반적으로 C++의 std :: string은 문자열 유형이며 표준 컨테이너이므로 표준 알고리즘으로 검색 할 수 있습니다. 좀 더 구체적인 조언이 필요하다면, 당신이하려는 일을 정확하게 기술하고 C++로 질문하는 질문을하십시오. 유용한 조언을 줄 수있는 사람들이 많이 있습니다. 우선 먼저 약간의 다리 작업을 수행하십시오 (예 : C++ 문자열 유형 및 표준 알고리즘을 읽음). 먼저 노력을 보여 주면 사람들이 도움을받을 수 있습니다. – Peter

관련 문제