C 프로그래밍
<자료의 입출력>
1. 개 요
우리가 컴퓨터를 이용하는 근본적인 목적은 컴퓨터로 하여금 인간을 대신하여 일을 할 수 있게 하기 위함이다. 컴퓨터의 이용에서 가장 보편적인 작업은 자료처리이고 이 자료처리에서 가장 우리 인간과 관계가 깊은 것은 자료의 입출력이라고 할 수 있다.
일반적으로 C언어 시스템은 라이브러리를 갖고 있는데 기본적인 산술함수들은 산술 라이브러리에에서 제공되고 입출력 함수들은 표준 라이브러리에서 제공된다. 이번 보충학습을 통해서는 printf()와 scanf()를 중심으로 살펴보기로 한다.
2. 출력 함수
가장 보편적으로 이용되는 출력함수는 printf()로 크게 두 가지 장점을 갖고 있다. 하나는 인자(parameter) 리스트를 구성할 때 길이에 제약이 없다는 것이고 다른 하나는 출력의 제어가 간단한 변환형식(format)에 의해 이루어 진다는 점이다. 즉 사용자가 직접 필요한 변환을 하지 않아도 되며 printf() 함수는 표준출력 파일 stdout에 문자스트림을 전달하게 된다. 이러한 printf()함수의 매개변수 리스트는 제어문자열과 인자 리스트의 두 부분으로 이루어 진다.
는 거 fh 는 출력에 사용되고, 함수 scanf()는 입력에 사용된다. 기술적으로 이들 함수들은 C 언어에 속하지 않으며, 그것보다는 C 시스템에 속한다. 표준 라이브러리에 있으며, C 시스템이 상주할 때 이용이 가능하다. printf()와 scanf()의 f는 “포맷이 되었다(formatted)"는 것을 나타낸다. 두 함수 모두 제어 문자열과 인수 리스트 두 부분으로 이루어진 파라메터 리스트를 갖는다.
printf("she sells %d %s for $%f", 99, "sea shells", 3.77);
위에서 제어 문자열은 "she sells %d %s for $%f"이고 인자 리스트는 99, "sea shells", 3.77가 된다.
이때 제어문자열은 문자열로 변환명세 또는 형식을 포함한다. 변환명세는 % 문자로 시작되고 변환문자로 끝낸다. 예를 들어 형식 %d에서 문자 d는 변환문자이다. 이미 보았듯이 이 형식은 식의 값을 십진 정수로 프린트할 때 이용된다. 화면에 문자 ABC를 프린트하기 위해 우리는 문장 printf("ABC")를 사용할 수 있다. 또 다른 방법으로 printf("%s", "ABC")를 쓴다. 형식 %s는 변수 “ABC"를 문자열의 형식으로 프린트한다. 또 하나의 방법으로 printf("%c%c%c", 'A','B','C');라 쓸 수 있다.
한 개의 인용부호는 문자상수를 지정하는데 이용된다. 이와 같이 ‘A'는 대문자 A에 대응하는 문자상수이다. 형식 %c는 식의 값을 문자로 프린트한다. 상수는 그 자체 식으로 간주됨을 주의해야 한다.
문자상수 이외에도 C 언어는 자료형 char의 변수를 제공하는데, 이는 문자값을 다루는 데 이용될 수 있다.
char c1, c2, c3;
c1 = 'A';
c2 = 'B';
c3 = 'C';
printf("%c%c%c", c1, c2, c3);
예를 들어 선언 char c1, c2, c3;는 컴파일러에게 변수 c1, c2 및 c3가 char형이라는 것을 알려주며 위의 코드도 문자 ABC를 화면에 프린트할 것이다. 변수이름은 그 자체가 식으로 간주됨을 주의한다. 일반적으로 사용되는 변환문자의 예를 들면 아래와 같다.
printf() | ||
변 환 문 자 |
대응되는 인수가 출력되는 형태 |
예 |
c |
문자 |
k |
d |
10진 정수 |
45 |
e |
지수형의 부동 소숫점수 |
-7.001100e+03 |
f |
부동 소숫점수 |
-7001.100000 |
g |
e-형식 또는 f-형식, 어느 쪽이든 짦은 형태 |
-7001.1 |
s |
문자열 |
Pacific |
o |
8진 정수s |
55 |
x |
16진 정수 |
2d |
u |
부호없는 십진 정수 |
45 |
인수가 프린트될 때 프린트되는 장소를 필드(field)라 부르고, 이 필드의 문자수를 필드폭이라 부른다. 필드폭은 형식에서 %와 변환문자 사이에 나타나는 정수로 정의된다. 이와 같이 문장 printf("\n%3c%5c%7c", 'A', 'B', 'C'); 는 다음과 같이
A B C
를 프린트할 것이다.
3. 입력 함수
함수 scanf()는 함수 printf()와 유사하며 다음의 두 가지 특성을 갖고 있어 융통성이 매우 높다. 하나는 인자의 길이에 제한이 없다는 것이고 다른 하나는 변환에 필요한 세부 사항을 사용자가 몰라도 간단한 변환형식에 의해 입력이 제어된다는 것이다. 이러한 scanf() 함수도 매개변수 리스트는 제어 문자열과 인자 리스트의 두 부분으로 구성된다.
이 함수의 첫 번째 인수는 입력 스트림에서 대응되는 형식을 갖는 제어 문자열이다. 인수 리스트는 변수에 대한 주소로 구성된다. 기호 &는 주소 연산자를 나타낸다. 예를 들어 문장
scanf("%d", &x);
는 scanf()가 입력문자를 십진정수로 해석하고 x의 주소에 값을 저장시킬 수 있도록 형식 %d를 포함한다. 프로그램에 값을 입력시키기 위해 키보드를 사용할 때 문자들의 열이 타자되고 프로그램은 이를 수용한다. 이 열을 ‘입력 스트림’이라 불린다. 만일 1337이 타자되면 타자한 사람은 그것을 십진정수로 여기지만, 프로그램은 그것을 문자들의 열이라고 간주한다. scanf() 함수는 십진수의 열을 정수값으로 변환하고, 그것을 적당한 장소에 저장하는 데 이용하는데 scanf()와 관련된 변환문자는 아래와 같다.
scanf() | |
변 환 문 자 |
입력열이 변환되는 형태 |
c |
문자 |
d |
10진 정수 |
f |
부동 소숫점수(float) |
lf |
2배 정도의 수(double) |
s |
문자열 |
x |
16진수 |
o |
8진수 |
u |
부호 없는 십진 정수 |
다음 프로그램은 printf() 와 scanf() 함수를 사용한 예를 보이고 있다.
main()
{
char c1, c2, c3;
int k;
float x;
double y;
printf("\n%s\n%s\n%s\n%s",
"input the following: three characters,",
" an int,",
" a float,",
" and a double: ");
scanf("%c%c%c%d%f%lf", &c1, &c2, &c3, &k, &x, &y);
printf("\nhere is the data that you typed in:\n");
printf("%3c%3c%3c%5d%l7e%l7e\n\n", c1, c2, c3, k, x, y);
만일 프로그램을 컴파일하고 실행시켜 ABC, 3, 55, 77.1을 입력한다면 다음과 같은 결과가 화면에 나타난다.
input the following: three characters,
an int,
a float,
and a double: ABC 3 55 77.1
here is the data that you typed in:
A B C 3 5.500000e+01 7.710000e+01
수를 읽을 때 scanf()는 공간(공백문자, newline, 탭)을 건너 뛸 것이다. 그러나 문자를 읽을 때는 그렇지 않다. 따라서 입력 AB C 3 55 77.1에 대해서는 프로그램이 바르게 실행하지 않는다. 입력된 세 번째 문자는 공백문자로 실효성 있는 문자이다. 그러므로 scanf()는 C를 10진 정수로 읽어 여기에서 문제가 발생한다.
printf()와 scanf() 차이점 중의 하나는 서식 %f에 관계된다. printf()에 있어서 이 형식은 변수의 값을 float형이나 double형으로 프린트할 때 이용된다. 대조적으로 scanf()가 숫자를 입력하고 변수의 주소에 저장하기 위해 이용될 때, 형식 %f는 변수가 float형일 때, 그리고 %lf는 변수가 double형일 때 이용된다. 이 문장에서 문자 ‘l'은 ’long'을 나타내고, ‘long float'는 ’double'과 같은 의미를 나타낸다.
특히 scanf()의 경우 *가 변환문자에 있으면 그 입력 양식은 건너뛰고 입력 스트림에 있는 %문자를 무시하려면 %%를 사용하면 된다. 아래의 프로그램은 그 예를 보이고 있다.
main()
{
int I;
char c;
char string[15];
scanf("%d , %*s %% %c %5s %s", &i, &c, string, string[5];
}
위에서 만약 입력 스트림이 45, ignore_this % C read_in_this* *일 경우 45는 I 의 값이 되고 쉼표는 제어문자열 값과 일치하며 문자열 ignore_this는 무시된다. 또한 %는 제어 문자열과 일치하며 문자 C는 변수 c에, 문자열 read_는 string[0]에서 string[4]까지에 저장되고 \0라는 널문자는 string[5]에 저장된다. 그리고 다시 in_this**는 \0과 함께 string[5]부터 string[14]에 저장된다.
두 함수간의 또 하나의 차이점은 printf()는 값을 반환하지 않은 데 반하여, scanf()는 값을 반환한다. 이것은 올바르게 수행된 변환의 수를 int형의 값으로 반환한다. 마지막 프로그램에서 scanf()에 의해 반환된 값의 어떤 사용도 없었으나 제어의 흐름을 설명할 때 반환된 값에 대해서는 자세하게 다루기로 한다.
'컴퓨터 > 언어,프로그래밍' 카테고리의 다른 글
[C언어] C언어 변수 (0) | 2009.03.17 |
---|---|
[C언어] C언어 선행처리기 (0) | 2009.03.17 |
[C언어] C언어 조건문 (0) | 2009.03.17 |
[C언어] C언어 반복문' (0) | 2009.03.17 |
[C언어] C언어 문자 입/출력 (0) | 2009.03.17 |