3/28 프로그래밍기초 4주차
주제: 표준입출력
영어단어:
- socket
- token
표준입출력
- 표준입출력은 실제 사용 X
- 실무코드임
대표적 3가지
1. printf() / scanf()
- scanf()는 문제를 발생시킴
- 파라미터 [()]가 %d (정수) 라면 뒤에 주소를 넣음
- 파라미터 주소로 인해 버퍼오버플로우 공격의 취약점을 가짐
- 그래서 scanf() 대신 scanf_s()를 사용해서 버퍼오버플로우 공격을 피함
- scanf_s()의 문제는 visual studio에는 문제가 안생기는데, GCC 컴파일러에는 사용을 할 수 없음 -> 범용성이 떨어짐
2. getchar() / putchar()
- 문자를 하나밖에 사용못해서 보안에 취약함 그래서 이거도 잘 안씀
3. gets() / puts()
- 문자열 입력에 사용
- 또한 gets 파라미터에 버퍼 오버플로우 공격 문제가 생김
버퍼 오버플로우 해결방법 [fgets]
- 주로 실무코드에서 사용
- fgets() 사용
- "문자열" 엔터로 함 (엔터가 token)
- token을 다른말로 구분자라고 함
- 파라미터안은 3개로 사용:
1. 버퍼이름
2. 읽을 크기
3. 어디서 읽을지 (읽을 대상)
- stdin 이라고 지정하면 (키보드 입력을 받음)
- file 객체명을 지정하면 (그 파일로부터 읽어오라는 것)
- socket 이라고 지정하면 (네트워크에서 읽어오는 것)
fgets()로 숫자 입력 처리
1. atoi()
- ascii 2 integer라고 함
- 파라미터안이 버퍼
- 버퍼 0번지부터 한글자씩 읽어서 숫자로 변하는 방식
- 변환 실패 시, 0을 리턴
- #include<stdlib.h> 를 사용해야함
- "1abc엔터" 전부 입력시 -> 잘못된 문자열(abc)로 할 판단불가
strcpn()
- fgets() 입력 문자열의 마지막을 끝문자로 변환해야함 -> strcspn() 사용 권장
- #include<srting.h> 사용해야함
- 파라미터는 2개로:
- 버퍼
- 찾을글자
2. strtol() / strtof()
- #include<stdlib.h> 를 사용해야함
- 1abc 입력시 숫자가 끝난지점에 포인터를 남겨줌
- 파라미터는 3가지:
1. buf
- 변화할 문자열
2. char*
- 변환이 끝난 직후의 문자위치 (포인터)
- 123abc로 입력하면 a로 시작하는 위치 알려줌
3. 진법
- 몇진수로 해석할지 정함
코딩
- 안내 출력
- fgets() 문자열 입력
- 숫자형문자 맞는지 판단
3.1. a=atoi() 변환이 0을 반환하는지
- if(a==0 && buf[0] != '0') print("못바꿈") 이면 첫글자가 숫자가 아니면 바로 0을 뱉음
과제
// strtof() 함수를 사용하여 실수 값 입력 처리 함수를 작성하시오.
#include<stdio.h>
#include<stdlib.h> //strtof() 라이브러리
#include<string.h> //strcspn() 라이브러리
void usingStrtof();
int main()
{
usingStrtof();
return 0;
}
void usingStrtof()
{
printf("fget() / strtof() 실수 입력 실습\n");
char buf[20]; // 실수 입력 버퍼
char* endPtr; //strtof()이 변환을 멈춘 위치를 가리키는 포인터
float value; //strtof()은 float 타입을 반환하므로 float으로 선언
printf("실수 입력: ");
if(fgets(buf, sizeof(buf), stdin) != NULL) //NULL 반환인지 확인
{
buf[strcspn(buf, "\n")] = '\0'; // 개행문자 제거
value = strtof(buf, &endPtr); // 문자열을 float으로 변환
if (endPtr == buf || (*endPtr != '\0' && *endPtr != '\n')) //변환이 전혀 이루어지지 않은 경우
{
printf("유효한 실수가 아닙니다.\n");
}
else {
printf("입력한 실수는 %f입니다.\n", value);
}
}
}