클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

변수와 데이터 입력 2 - 데이터 입력 본문

프로그래밍 언어/C 언어

변수와 데이터 입력 2 - 데이터 입력

huenuri 2024. 7. 30. 04:48

출력하는 방법에 대해서 배웠으나 입력이 있어야 진짜 제대로된 출력이 완성된다. 프로그램을 이용해 우리가 원하는 결과를 얻으려면 그 결과 처리에 필요한 데이터를 입력할 수 있어야 하기 때문이다.

이번 단원에서는 프로그램을 실행하는 도중에 정수, 실수, 문자, 문자열을 입력하는 방법에 대해 학습해볼 것이다.

 

시작하기 전에

키보드에서 타이핑하는 모든 내용은 문자로 인식된다. 따라서 입력한 데이터를 연산이 가능한 정수나 실수로 사용하려면 변환 과정이 필요하다. 이때 사용하는 것이 바로 scanf 함수이다.

이 함수는 입력 문자들을 스캔해 원하는 형태의 데이터로 바꾸어 준다. 어떤 데이터로 변환할 것인지는 변환 문자를 통해 결정된다.

scanf 함수에서 자료형에 따라 사용하는 변환 문자는 printf 함수로 출력할 때 사용하는 변환 문자와 거의 같다.

 

 

 

 

1. scanf 함수의 사용법

 

scanf 함수는 키보드에서 입력한 값을 변수에 저장할 때 사용한다. 사용법은 간단하다. 변수의 형태에 맞는 변환 문자를 사용하고 입력할 변수 앞에 &(앰퍼샌드)를 붙이면 된다.

 

📖 scanf와 scanf_s 함수의 차이점은 무엇일까?

scanf를 사용하면 입력 크기에 제한이 없어서 지정된 크기보다 더 많은 양을 입력 받는 버터 오버플로(buffer overflow)라는 메모리 문제가 발생한다.

scanf_s는 이러한 오버플로우를 방지할 수 있다. int, float, double과 같은 자료형은 자료형의 크기가 일정하기 때문에 자료형을 입력 받는데 문제가 없지만, char, char[] 형태인 문자나 문자열에서는 입력 받을 크기를 반드시 뒤에 써주어야 한다.

scanf_s("%s", 문자열변수명, sizeof(문자열변수명));을 써주면 입력이 가능하다. 어떤 경우에는 sizeof 앞에 unsigned int를 써야 할 경우도 있고, 이를 생략하여 크기를 숫자로만 지정하는 것도 가능하다.

 

📖 버퍼 오버플로란 무엇인가?

프로세스가 데이터를 버퍼에 저장할 때 프로그래머가 지정한 곳 바깥에 저장하는 것을 의미한다. 버퍼는 데이터를 한 곳에서 다른 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리 영역이다. 즉 컴퓨터 안의 프로세스 사이에서 데이터를 이동시킬 때 사용되는 것이 버퍼이다.

데이터가 오버플로 되면 그 데이터는 오염이 되고, 이를 악용하여 악의적인 프로그래머들이 그 정보를 사용할 가능성도 아주 높기에 scanf_s를 권장한다. scanf_s는 scanf와 다르게 사이즈를 넘어서게 된다면 아예 저장을 하지 않는다.

 

🤠 scanf 함수 사용시 유의점

변수명을 저장할 때는 &를 붙여야 한다

사용한 변환 문자와 맞는 형태의 데이터를 입력해야 한다 : 정수, 실수, 문자열 등

 

scanf 함수를 사용한 키보드 입력

#include <stdio.h> 
int main(void) 
{ 
  int a; 
  scanf_s("%d", &a); 
  printf("입력된 값 : %d\n", a); 
  return 0; 
}

 

🤠 scanf 함수의 응용

scanf 함수는 여러 개의 변환 문자를 나열해 한번에 2개 이상의 변수에 값을 입력할 수 있다.

scanf("%d%lf", &a, &b);

변환 문자들은 큰따옴표 안에 이어서 나열되며 변수 사이는 콤마로 구분한다.

 

scanf 함수를 사용한 연속 입력

#include <stdio.h> 
int main(void) 
{ 
  int age; 
  double height; 
  printf("나이와 키를 입력하세요 : "); 
  scanf_s("%d%lf", &age, &height); 
  printf("나이는 %d살, 키는 %.1lf\n", age, height); 
  return 0; 
}

 

 

2. 문자와 문자열의 입력

 

char형 변수에 문자를 입력할 때는 키보드로 입력하는 모든 문자가 대상이 된다. 즉, space bar(공백 문자)나 enter(개행 문자)도 하나의 문자로 전달된다.

문자열은 char 배열에 %s 변환문자를 사용해 입력하는데, 배열명에 &를 붙이지 않는다. 또한 스페이스나 엔터, 탭 등을 만나면 바로 전까지만 저장되므로 공백 없이 연속으로 입력해야 한다.

 

문자와 문자열 입력

#include <stdio.h> 
int main(void) 
{ 
  char grade; 
  char name[20]; 
  printf("학점 입력 : "); 
  scanf_s("%c", &grade, (unsigned int)sizeof(name)); 
  printf("이름 입력 : "); 
  scanf_s("%s", name, (unsigned int)sizeof(name)); 
  printf("%s의 학점은 %c입니다.", name, grade); 
  return 0; 
}

 

 

배열의 크기가 20바이트이므로 최대 19자의 문자열을 입력할 수 있다. 문자열에서는 문자열의 끝을 표시하기 위해 널 문자를 사용해야 한다. 따라서 널 문자를 저장할 1바이트의 여유는 있어야 한다.

한글은 한 자당 2바이트를 차지하므로 9자까지 입력할 수 있다.

 

개행 문자를 입력할 경우

만약 학점을 입력할 때 Enter만 누른다면 Enter에 해당하는 제어 문자 \n이 grade 변수에 저장되고 이어서 바로 이름을 입력한다.

이름도 홍과 길동을 분리해서 입력하면 배열에는 '홍'만 입력된다.

 

학습 내용 정리

 


 

연습문제

 

🥟 문제 1

 

좋아하는 과일과 개수를 출력하는 프로그램을 만드시오.

 

#include <stdio.h> 
int main(void) 
{ 
  char fruit[20]; 
  int cnt; 
  printf("좋아하는 과일 : "); 
  scanf_s("%s", fruit, (unsigned int)sizeof(fruit)); 
  printf("몇 개 : "); 
  scanf_s("%d", &cnt); 
  printf("%s를 %d개 드립니다.", fruit, cnt); 
  return 0; 
}

 

🥟 문제 2

 

키보드로 문자를 입력해 아스키 코드 값을 출력하는 프로그램을 만들라.

 

#include <stdio.h> 
int main(void) 
{ 
  char ch; 
  printf("문자 입력 : "); 
  scanf_s("%c", &ch, 1); 
  printf("%c문자의 아스키 코드 값은 %d입니다.", ch, ch); 
  return 0; 
}

 

🥟 문제 3

 

나이를 키보드로 입력받되, 나이에 큰따옴표를 쳐서 출력하는 프로그램을 만들라.

 

#include <stdio.h> 
int main(void) 
{ 
  int age = 0; 
  printf("당신의 나이를 입력하세요 : "); 
  scanf_s("%d", &age); 
  printf("당신의 나이는 \"%d세\"입니다.", age); 
  return 0; 
}

🥟 문제 4

국어, 영어, 수학 세 과목을 성적을 키보드로 입력 받아 총점과 평균을 출력하는 프로그램을 만드시오.

 

#include <stdio.h> 
int main(void) 
{ 
  int kor, eng, mat; 
  int tot; 
  double avg; 
  printf("총점과 평균을 구하는 프로그램입니다.\n"); 
  printf("국어 점수를 입력하고 Enter를 누르세요 : "); 
  scanf_s("%d", &kor); 
  printf("영어 점수를 입력하고 Enter를 누르세요 : "); 
  scanf_s("%d", &eng); 
  printf("수학 점수를 입력하고 Enter를 누르세요 : "); 
  scanf_s("%d", &mat); 

  tot = kor + eng + mat; 
  avg = tot / 3.0; 
  printf("당신의 총점은 %d이고, 평균은 %.1lf입니다.", tot, avg); 
  return 0; 
}

🥟 문제 5

 

인치 단위로 입력 받아서 cm로 환산하여 출력하는 프로그램을 만드시오.

 

#include <stdio.h> 
int main(void) 
{ 
  int inch = 0; 
  double cm; 
  printf("인치를 입력하세요 : "); 
  scanf_s("%d", &inch); 
  cm = 2.54 * inch; 
  printf("%d인치는 %.2lfcm입니다.", inch, cm); 
  return 0; 
}

 

두 권의 책에서 나오는 연습문제를 풀어보았다. 가능하면 정답을 보지 않고 풀려고 노력했다. 예시로 나오는 것도 가리고 출력문만 보면서 풀어보았는데 대부분 혼자서 풀 수 있었다.

 


학습을 마치고

 

일요일에 학습하려고 했던 단원을 오늘이라도 마칠 수 있어서 참 감사했다. 매일 한 주제에 관한 단원을 마치려고 한다. 앞부분은 그래도 좀 쉬우니 진도를 빨리 빨리 나가고 함수부터는 조금 천천히 학습할 생각이다.

처음에는 C++만 학습하려고 했는데, C++은 C를 안다는 전제하에 설명하고 있어 C는 기본 중의 기본이었다.

지난번에 공부를 다 마쳤다고 생각했는데 사실 그때는 프로그래밍의 기초적인 부분도 알지 못한 상태에서 학습한 거라 이해력이 많이 떨어졌었다. 다시 공부해보니 이전에 알던 건 진짜로 아는 게 아니었음을 느꼈다.

전에는 scanf 함수와 scanf_s의 차이점도 잘 몰랐는데 이제는 둘다 어떤 차이가 있으며 어떻게 사용하지는도 쉽게 알 수 있었다.