Programming/C C++
1. 한문자 입출력

한문자의 입력과 출력은 getchar()와 putchar()함수를 이용합니다.(getchar()와 putchar()함수는 stdio.h에 정의되어 있습니다.)

#include <stdio.h>

main()
{
  int c;
 
  while((c = getchar()) != EOF){
    putchar(c);
  }
}


getchar()함수를 통해 한문자를 입력받고 putchar()함수로 입력받은 값을 출력합니다.

이 Program은 while문을 통하여 반복적으로 getchar()함수를 호출하여 사용자로부터 한문자를 입력받도록 합니다. 이때 while문을 벗어나려면(입력을 중지하려면) Ctrl + C를 동시에 누르시면 됩니다. 그러면 getchar()함수는 EOF를 반환(putchar()함수도 오류가 생기면 EOF를 반환합니다.)하고 결국 while문을 벗어날 수 있게 됩니다.


주의:
한문자를 입력받아 저장하는 변수로 char형을 사용하면 될것같지만 사실 그다지 안전하지 않은 방법입니다. 왜냐하면 getchar는 입력종료시 -1을 반환하는데 이는 System환경에 따라 char형이 -값을 제대로 받지 못하는 경우가 있기 때문입니다.(32bit나 64bit환경에서는 대부분 이러한 문제가 발생하지 않습니다.)

2. 한행의 입출력

행단위의 입력과 출력은 gets()함수와 puts()함수를 이용합니다.(getchar()와 putchar()함수는 stdio.h에 정의되어 있습니다.)

#include <stdio.h>

main()
{
  char s[80];
 
  while(gets(s) != NULL)
    puts(s);
}


gets()함수로 한행을 입력받아 puts()를 통해 입력받은 값을 출력합니다.

Program에서 while문의 반복조건으로 NULL을 주었는데 이는 gets()함수가 getchar()함수와는 다르게 입력중지시(오류발생시) NULL값을 반환하기 때문입니다.

puts()함수는 한행을 출력하는 함수이며 한행출력과 동시에 개행을 하게 됩니다. puts()함수는 출력 후 개행하는 동작을 막을 수 없습니다.


3. 형식화된 입출력

getchar(), putchar(), gets(), puts()함수는 단순한 입력과 출력를 수행할 뿐입니다. 이 와는 다르게 입력과 출력에 다양한 서식을 지정하려면 scanf()와 printf()함수를 사용해야 합니다.

scanf()와 printf()함수의 이름에서 끝에 f는 format의 앞자로서 서식을 지정할 수 있는다는 것을 의미합니다.

#include <stdio.h>

main()
{
  char c;
  char s[80];
  int i;
 
  scanf("%c", &c);
  printf("문자 출력 : %c\n", c);
 
  scanf("%s", s);
  printf("문자열 출력 : %s\n", s);
 
  scanf("%d", &i);
  printf("정수 출력 : %d\n", i);
}


scanf()함수에서 입력을 받고 printf()함수를 통해 입력받은 값을 출력합니다.(scanf()에서 문자열 입력시 공백은 읽지 않습니다. 단 문자는 예외)

보시는 바와 같이 scanf()함수는 변수에 값을 입력하기 위해 변수명 앞에 &문자를 붙여 변수의 주소를 지정해 주고 있습니다. 그런데 두번째 scanf()함수를 보시면 &를 붙이지 않았습니다. 이는 문자열의 경우 문자배열명 자체가 주소를 가리키고 있기 때문입니다. 따라서 문자배열의 이름에서는 주소를 의미하는 &를 붙이지 않는 것입니다.


scnaf()함수와 printf()는 '% + 문자' 의 형식으로 입력값과 출력값에 대한 Data형식(format)을 지정할 수 있는데 이때 %로 시작하는 문자열 형태를 '변환 문자열'이라고 합니다. 이 변환문자열의 형식은 scanf()함수나 printf()함수에 동일하게 적용할 수 있습니다.

 변환 문자열  설명
 %o  8진수
 %d  10진수
 %ld  long형 10진수
 %x(또는 X)  16진수
 %u  unsigned형 10진수
 %f  실수
 %lf  double 실수
 %e (또는 E)  지수
 %g (또는 G)  실수 출력시 0까지 모두 표시
 %c  문자
 %s  문자열

printf()함수는 어떠한 Data를 출력할때에 원하는 만큼의 자리 수 내용 까지만 출력할 수 있습니다. 이때 자리 수 지정 형식은 다음과 같이 변환 문자열과 혼용하여 사용합니다.

%자리수+변환문자 

다음은 printf()함수에 자리 수를 지정한 예제입니다.

#include <stdio.h>
#include <string.h>

main()
{
  char s[11];
  int i;
  float f;
 
  strcpy(s, "helloworld");
  i = 123;
  f = 12.34;
 
  printf("문자열 예제\n");
 
  printf("%s\n", s);
  printf("%15s\n", s);
  printf("%-15s\n", s);
  printf("%5s\n", s);
  printf("%15.5s\n", s);
 
  printf("정수 예제\n");
 
  printf("%d\n", i);
  printf("%10d\n", i);
  printf("%-10d\n", i);
  printf("%+10d\n", i);
  printf("% 10d\n", i);
  printf("%010d\n", i);
  printf("%2d\n", i);
  printf("%10.2d\n", i);
 
  printf("실수 예제\n");
 
  printf("%f\n", f);
  printf("%7f\n", f);
  printf("%-7f\n", f);
  printf("%3f\n", f);
  printf("%5.1f\n", f);
}


첫번째 printf()는 변환문자열만 지정한 기본적인 사용법을 보여주고 있습니다.

두번째 printf()함수에서 쓰인 숫자는 출력되는 전체적인 자리수를 의미하며 세번째 printf()함수에는 이 자리수를 지정하는 숫자앞에 - 문자를 포함시켜 출력되는 Data내용을 왼쪽정렬하였습니다.(정수예제에서의 4번째 printf()처럼 +를 붙일경우 Data를 출력할때 앞에 -/+부호를 표시하겠다는 의미가 됩니다.)

문자열과 실수에서의 네번째 printf()함수에서는 두번째 사용방법과 마찬가지로 전체적인 자리 수를 지정했는데 만일 이 전체자리수가 실제 출력되는 Data의 자리수와 맞지 않으면(더 작으면) 해당 Data를 자르지 않고 그대로 출력하게 됩니다.

문자열과 실수에서의 다섯번째 printf()함수는 자리 수 지정을 소수점을 사용하였습니다. 이 것은 만일 10.5 라고 했을 경우 전체 자리 수는 10이되 실제 Data는 5자리수만 표시하도록 지정하는 것입니다.

위와 같이 자리 수를 지정하면 전체적인 자리수를 지정할 때와는 달리 지정한 자리수(소수점 이하 수)가 실제 Data출력과 작을 경우 나머지 부분은 잘라서 출력하게 됩니다.(단 정수 출력의 경우에는 자르지 않습니다.)

정수예제에서의 5번째 printf()함수는 단순한 공백을 주어 Data출력시 한칸을 띄우도록 하였습니다. 이는 이전에 수치Data를 출력할때 %+를 통하여 부호를 표시하도록 할때 다음 출력부분에서 자리위치가 맞지 않아 들쭉날쭉한 출력모양새가 되는 것을 방지위해 자주 쓰이는 방법입니다.

정수예제에서 6번째 printf()함수에서는 %0을 지정하여 수치Data출력 후 남은 공백부분을 모두 0으로 채워지도록 하였습니다.


scanf()로 Data를 입력받을때는 개발자가 원하는 Data만 받을 수 있도록 []를 통해 지정할 수 있습니다.

#include <stdio.h>

main()
{
  char s[80];
 
  scanf("%[abc]s", s);
  printf("문자열 출력 : %s\n", s);
}


입력받는 내용중 a, b, c 세개의 문자에 해당하는 내용만 입력받도록 합니다.


이 외에도 반대는 ^문자를 추가하여 [^abc]등으로 할 수 있으며 -을 사용하면 [a-d](a부터 d까지)등으로 범위를 지정할 수 있습니다.

4. Memory로 부터의 입출력

getchar(), putchar(), gets(), puts(), scanf(), printf()함수는 모두 keyboard로 부터 입력을 받고 화면을 통해 출력하는 함수이지만 지금 부터 설명해드릴 sscanf()함수와 sprintf()함수는 Memory의 특정영역에 있는 Data를 통해 입력을 받고 그 내용을 다시 특정 Memory영역에 출력하도록 합니다.

#include <stdio.h>

main()
{
  char s[11] = "helloworld\0";
  char cp[11];
  char pp[11];
 
  sprintf(cp, "%s", s);
 
  sscanf(cp, "%s", pp);
 
  printf("%s\n", cp);
  printf("%s\n", pp);
}


sprintf(cp, "%s", s); 부분에서는 sprintf()함수를 통해 s가 지시하고 있는 주소의 Memory에 있는 Data를 문자열 형식(%s)으로 읽어 이를 cp가 지시하고 있는 주소영역에 출력합니다.(s주소에 있는 Data를 cp주소에 씁니다.)

그런다음 다시 sscanf(cp, "%s", pp);를 통해서 cp의 주소에 있는 Data를 문자열 형식으로 pp주소영역에 입력받도록 합니다.(cp주소에 있는 Data를 pp주소에 씁니다.)


참고 :
sscanf()함수는 오류 발생시 EOF를 sprintf()함수는 -값을 반환합니다.
0 0