scanf를 통하여 공백이 있는 문제열을 입력 받지 못하여 애를 먹였는데, 아래와 같은 방법이 있네요.

- 방법은 문자열 입력 조건을 통하여 처리하는 것입니다.

- 문자열 조건은 []을 통하여 넣을 수 있습니다. 

 

[[[예제]]] 

ㆍchar str[80];

   scanf("%[12345]s", str);

// 입력이 "4567" 이면 str에 "45" 가 기억

 

ㆍchar str[80];

   scanf("%[^12345]s", str);

// 입력이 "6745" 이면 str에 "67"dl rldjr

// ^ 는 [ ] 안 이외의 문자만 입력 허용

 

ㆍchar str[80];

   scanf("%[0-9]s", str);

// 입력이 "45ab" 이면 str에 "45" 가 기억

// 0-9 는 0123456789 와 동일

  

[[[ 공백을 포함한 문자열 입력 방법]]]

 

char str[80];

   scanf("%[^\n]s", str);

// '\n'(new line) 문자를 만나기 전까지 입력을 받습니다.

 

ㆍchar str[80];

   scanf("%79[^\n]s", str);

// '\n'(new line) 문자를 만나기 전까지 입력을 받되, 79자 까지만 입력을 받습니다.

 

ㆍchar str[80];
   scanf("%[a-zA-Z]s", str);

// 영문자만 입력을 받습니다.

 

 ps. gets()는 입력받을 글자수의 제한할 수 없음.

      제한을 두고 싶을땐 sacnf() 함수 사용.

 

 

----------------------------------------------------

c언어에서 가끔 발생하는 문제가 scanf로 입력받다가
입력버퍼가 다 비워지지 않아서 문자입력받는게 씹히는 경우가 생긴다.
c언어 공부하다보면 꼭 한번쯤은 겪어보는 문제
예를 들면

#include <stdio.h>

int main()
{
        char string[20];
        char c;

        scanf("%s", string);
        scanf("%c", &c);

        printf("%s\n", string);
        printf("!!%c!!\n", c);

        return 0;
}

실행 결과는?

문자열만 입력받아버리고 프로그램이 끝나버린다.

원인은
scanf("%s", string);
가 실행되고 나서 입력버퍼에는 개행문자가 그대로 남아있는 거다.

그래서 
scanf("%c", &c);
를 실행하려고 보니 버퍼에 개행문자가 있어서 그걸 c에다 넣어버린거다.
정작 표준입력으로는 아무것도 입력안했는데
예전에 이걸 몰라서 개고생한거 생각하면..

해결방법은
입력버퍼를 비우면 된다.

어떻게?
        scanf("%s", string);

       scanf("%c", &c);
이 두 사이에 입력버퍼를 비워주는 뭔가를 해주면 된다.

1. 간단하게는 getchar(); 를 추가하는 걸로도 가능

2. fflush(stdin); 추가
그런데 이건 gcc에서 안돌아간다. 왜? 당연히 안된다. 표준 fflush함수는 출력버퍼를 비우는 녀석이다.
VC에서는 확장해서 사용하므로 동작하지만 gcc는 안된다.

3. tcflush(0, TCIFLUSH); 추가
0번 디스크립터를 비워라. 그런데 이는 유닉스 계열에서 터미널과 관련된 함수인 듯

4. rewind(stdio); 추가
rewind함수는 매개변수로 들어온 스트림을 초기화하는데 사용

5. 
__fpurge(stdin);
이놈도 리눅스에서만 동작하고 표준은 아니다. stdio_ext.h 추가.

6. 
fgets(string, sizeof(string), stdin);
문자열 입력을 scanf가 아니라 fgets로 받는다.
그러나 입력시 사이즈를 오버하면 똑같은 문제가 발생한다.
그리고 사이즈를 오버하지 않더라도 문자열 끝에 개행문자가 추가된다.

그래서 다음 줄에
string[strlen(string)-1] = '\0'; 로 강제로 널문자를 넣어준다.
개인적으로 제일 많이 사용하는 방식

7. scanf("%*c", c);
%*c는 입력은 받지만 저장은 안한다. 즉 비어있는 \n를 날려버린다.

8. scanf("%c", &c);를 scanf(" %c", &c); 로
%c 앞에 공백을 추가하면 white space를 구분자로 인식한다.


입력들이 간단하게 위와 같이 나온다면 위의 방법들 아무거나 사용해도 되지만
복잡한 입력에 입력버퍼에 뭔가 많이 남는다면
버퍼를 비우는 것이 근본적인 해결방법인듯 하다.


출처 : http://blog.daum.net/jjiyong/18230445

'Development > C/C++' 카테고리의 다른 글

[Static Assert]  (0) 2014.04.16
[itoa, atoi 구현]  (0) 2014.03.04
[objdump in linux]  (0) 2014.01.15
[vim에서 hexedit하기, hex비교하기]  (0) 2014.01.15
[코드에서 endian을 파악하는 방법]  (0) 2014.01.06
Posted by cyj4369
,