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 |