프롤로그
ELITE HACKER Bootcamp 3rd 2주차 수업 공부 내용
aws 우분투 서버 하나 파서 연습
출력함수, 포멧 스트링, 이스케이프시퀀스, C언어의 입력함수, 문자열
출력 함수
이전 글들을 슥 돌아보면, 결과값들을 출력하기 위해서 주로 printf를 사용하였었다. 그 외에 몇 개 더 있는데, 알아보도록 하자.
(1) printf()
일반적으로 문자열을 포맷팅하여 출력하는 가장 많이 사용되는 함수이다.
printf("안녕");
이런식으로 많이 쓰인다.
(2) putchar
단일문자를 출력하는 함수이다.
putchar('A');
이런식으로 사용한다.
(3) puts
문자열을 출력하고 자동으로 줄 바꿈을 한다.
puts("Hello, World!");
이런식으로 사용한다.
실제로 한 번 써보자.
#include <stdio.h>
int main() {
printf("C 언어 출력 예제\n");
putchar('A');
puts("\n줄 바꿈 후 출력");
return 0;
}
실행하게 되면
printf와 putchar을 보게되면 자동으로 줄바꿈이 되지 않는다. 자동 줄바꿈이 되지 않기에 줄바꿈을 할려면 \n을 이용해서 줄바꿈을 시켜준다. 다만 puts를 하면 맨 뒤에 자동으로 \n이 붙어서 간단하다.
포멧 스트링
printf, putchar, puts 이런 것들 전부다 위에서는 문자들만 출력할 수 있게 되어있다.
근데 변수에 저장된 것은 어떻게 출력할 것인가?에 대해서 생각을 해보아야한다.
파이썬으로 따지면
a = 3
b = "a"
print(f"{a}, {b}}
이렇게 간단하게 하면 됐었다. 알아서 자동으로 변수의 자료형 결정해주니까. 근데 C언어는 굉장히 수동으로 프로그래머가 작성해줘야하지않는가? 그래서 출력하는 형태라던지, 출력하는 변수의 자료형이라던지를 직접 설정을 해줘야한다. 그것을 위해서는 포멧 스트링이란 걸 알아야한다.
이전글에서 C언어에서 정수를 출력하기 위해서
printf("%d", a);
이러식으로 사용했던 것을 보았을 것이다. %d 이걸 이제 포맷스트링이라고 한다.
즉, 포멧스트링이란, 출력 형식을 지정할 때 사용한다. 문자열 안에서 % 기호와 함께 자료형을 지정하는 포맷 지정자를 포함하여 사용되는데, 정수를 출력하기 위해서 decimal 의 약자 d를 %뒤에 붙여서 %d로 정수형을 출력하라 라는 의미로 쓰인다.
%d | 정수 (int) |
%u | 부호 없는 정수 |
%f | 실수 (float) |
%lf | 실수 (double) |
%Lf | 실수 (long double) |
%c | 단일 문자 |
%s | 문자열 |
%x | 16진수 (소문자) |
%X | 16진수 (대문자) |
%o | 8진수 |
%% | 퍼센트 기호 출력 |
%zu | 자료형 출력위함. 몇 바이트인지 |
그래서 좀 많이 쓰는 건, 정수 출력하기위한 %d, 실수 위한 %f(사실 lf나 f나 double 출력이라서 별 차이 없음), 문자 출력 %c, 문자열 출력 %s 정도이다.
#include <stdio.h>
int main(){
int a = 3;
float b = 3.5;
char c = 'a';
printf("%d, %f, %c\n", a, b, c);
return 0;
}
이렇게 된다.
실수형을 %d로 출력하려고 하면
오류가 난다.
출력 형식 제어
포멧 스트링을 기본적으로 사용할 때는
%[최소 폭].[정밀도][포맷 지정자]
이렇게 사용하여, 출력 시에 조금 더 세세하게 출력옵션을 줄 수 있다. 예를 들면 그냥 %f를 하게 되어버리면, 3.500000 이렇게 출력이 되는데, 소숫점 2번째 자리까지만 출력을 하고 싶다던지, 정수 앞 부분에 3이 아니라 03으로 출력을 시키고 싶다던지 이런 조건들을 설정할 수 있다는 의미이다.
(1) 최소폭
int a = 3;
int b = 15;
int c = 200;
이렇게 3개의 정수가 있다고 치자. printf로 출력한다면?
#include <stdio.h>
int main(){
int a = 3;
int b = 15;
int c = 200;
printf("%5d\n", a);
printf("%5d\n", b);
printf("%5d\n", c);
return 0;
}
안 에쁘다. 맨 뒤의 줄에 맞춰서 출력을 하고 싶어지는 상황에서 출력할 값의 최소 자리수를 지정하기 위해서 최소폭 옵션을 사용한다.
printf("'%5d'\n", a); // 출력: ' 3' (총 5칸, 4칸은 공백)
이런식으로 사용하는데,
전체 길이를 5자리를 두고 맨 뒷부분부터 채워넣어준다고 보면 된다. 전체 길이가 5자리라는 의미!
저대로 코드 수정해서 다시 출력해보면
#include <stdio.h>
int main(){
int a = 3;
int b = 15;
int c = 200;
printf("%5d\n", a);
printf("%5d\n", b);
printf("%5d\n", c);
return 0;
}
이렇게 맞춰졌다.
(2) 패딩
위에서 최소폭으로 출력 최대 길이를 지정해주었고, 출력하는 부분이 전체 폭보다 작으면 공백으로 채워졌다.
즉 최소폭 5이고, 3을 출력한다면 " 3" 이렇게 출력이 되었는데, 저 공백을 다른값으로 대체해서 채워줄 수 있다.
기본적으로 0만 가능하다.
printf("'%05d'\n", a); // 출력: '00003' (총 5칸, 4칸은 0)
이렇게 공백대신에 0으로 패딩을 채워넣었다고 보면된다.
(3) 정렬
최소폭이든 정렬이든 보면, 글자들이 오른쪽 정렬이 되어서 앞에 부분에 패딩인 0 또는 공백이 채워졌다. 저것을 왼쪽정렬로 만들려고 하는 것이다. -를 쓰면 되는데 이건 패딩은 안 되고, 공백에서만 사용가능하다.
printf("'%-5d'\n", b); // 출력: '15 ' (총 5칸, 3칸은 " ")
printf("'%5d'\n", b); // 출력: ' 15' (총 5칸, 3칸은 " ")
이걸 확인해보자.
#include <stdio.h>
int main(){
int b = 15;
printf("%-5d\n", b);
printf("%5d\n", b);
return 0;
}
이런 차이가 있다.
(4) 정밀도
정밀도는 출력의 소수점 이하 자릿수를 지정하거나, 문자열 출력 시 최대 출력 문자 수를 제한할 때 사용된다. 즉 맨 뒤 자리수 적당히 출력해라! 이거를 결정하는 것이다.
#include <stdio.h>
#define PI 3.141592
int main(){
double a = PI;
char str[] = "Hello";
printf("%.2f\n", a);
printf("%.4f\n", a);
printf("%.3s\n", str);
return 0;
}
이 코드를 출력해보자.
.2f로 했을 경우 딱 2자리 까지 출력되고
.4f로 했을 경우 딱 4자리 까지 출력되었다. 이 때 뒷부분은 버림이 아니라 반올림. 그래서 3.141592에서 3.1415가 아니라 3.1416이 출력이 된 것이다.
문자들을 char str[]로 출력이 된 것을 사용하였는데, 바로 알아보자.
문자열
생각을 해보자. 기존에 자료형에도 char 은 단어 한 글자만 입력받을 수 있다. 즉 'C', 'A' 이런식으로 받아야하고, 심지어 저거 입력받을 때도 "A" 이렇게 입력 자체가 안 된다.
그럼 Hello 이런 건 어떻게 입력받야아하는가?
char a = 'h'; char b = 'e' 이런식으로 일일이 해야하는가....?
문자열을 나타내기 위해서 문자의 배열 즉 char 의 배열을 이용한다.
문자의 배열로 표현되는데, 배열의 끝을 알리기 위해서 맨 마지막 글자에는 \0으로 끝나야 한다.
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str2[] = "Hello";
char *str3 = "Hello";
그래서 첫번째 방식 처럼 배열의 크기 할당하고, 맨 뒤에 \0을 직접할당하는 방법
두 번째는 뒤에 문자열이 주어지면 자동으로 \0 들어가고 크기 설정되는 방법
포인터를 이용하는 방법 3가지가 있다. 포인터는 나중에 다시 나올 것이다.
저 문자열들을 출력할 때 이제 %s를 이용하는 것이다.
\0은 대체 뭐냐? NULL값이다. 널 문자로 끝나지 않으면 문자열 함수 사용 시 오류가 발생할 수 있다. 배열 크기는 문자열 길이 + 1이 필요한데, 그 이유는 \0때문인 거 계속 강조한다.
입력 함수
출력을 하는 것도 있었고, 출력하기 위해서 포멧 스트링에 대해서도 알았다. 이제 입력을 배울건데, 입력을 받기 위해서도 똑같이 출력 때 처럼 포멧 스트링을 이용한다.
(1) scanf()
가장 많이 사용되는 입력 함수로, 다양한 자료형의 데이터를 입력받을 수 있다.
#include <stdio.h>
int main(){
int a;
scanf("%d", &a);
printf("%d\n", a);
return 0;
}
scanf("포멧스트링", &변수); 이렇게 하면 변수에다가 입력받은 값을 넣겠다라는 의미가 된다.
공백을 포함하지 않는 단어 단위로 문자열을 입력받기에, 엔터 입력한 게 문제가 발행할 수 있다. 그래서 getchar()를 이용해서 버퍼 비우기도 한다.
#include <stdio.h>
int main(){
int num;
char str[50];
printf("정수를 입력하세요: ");
scanf("%d", &num); // 정수 입력
printf("문자열을 입력하세요: ");
scanf("%s", str); // 공백이 없는 문자열 입력
printf("입력된 정수: %d\n", num);
printf("입력된 문자열: %s\n", str);
}
공백을 입력했더니 위에처럼, world는 출력이 안 되는 것을 볼 수 있다.
왜냐? %s %d 이런 것들은 공백을 기준으로 분리 되기 때문이다. 그래서 만약에 공백을 기준으로 받을려면.. %s %s 이런식으로 입력받아야 한다. 그리고 주의해야할 부분이
정수 같은 경우에는 & 이걸로 입력을 받는데, 문자열을 입력받는 str은 &가 붙지 않는다. 포인터 내용이라 후반에 얘기하겠다.
(2) getchar()
단일 문자를 입력받는 함수다. 아까 putchar과 비슷하다.
char ch;
printf("문자 하나를 입력하세요: ");
ch = getchar(); // 한 문자 입력
printf("입력된 문자: %c\n", ch);
(3) fgets
fgets(문자열 변수, 크기, 입력 스트림);
이렇게 설정하는데, 지정한 버퍼 크기만큼 입력을 받을 수 있다.
char str[100];
printf("문자열을 입력하세요: ");
fgets(str, sizeof(str), stdin); // 최대 sizeof(str)-1 만큼의 문자열 입력
printf("입력된 문자열: %s\n", str);
만약에 1000글자를 입력했다 하더라고 99글자까지만 입력이 되고 맨 마지막에는 \0에 들어간다. 나머지 901 글자는 어디로 가냐? 버퍼에 아직 남아있다. 그래서 버퍼를 비워주는 과정이 필요하다.
아 얘는 공백입력 가능하다.
이스케이프시퀀스
문자열이나 문자 상수 안에 특수 문자를 표현할 때 사용한다. 줄바꿈 \n, 탭 \t 이런 것들인데, 백슬래쉬로 시작한다.
\n | 줄 바꿈 (New Line) | 출력 시 줄을 바꾸어 다음 줄로 이동 |
\t | 탭 (Tab) | 수평 탭을 삽입 |
\\ | 백슬래시 (\) 출력 | 백슬래시 자체를 출력 |
\" | 큰따옴표 (") 출력 | 큰따옴표를 문자열 내에서 출력 |
\' | 작은따옴표 (') 출력 | 작은따옴표를 문자 또는 문자열 내에서 출력 |
\b | 백스페이스 (Backspace) | 한 글자를 지우는 동작 |
\r | 캐리지 리턴 (Carriage Return) | 현재 줄의 맨 앞으로 커서 이동 |
\f | 폼 피드 (Form Feed) | 페이지 넘김 동작 (프린터에서 사용) |
\a | 경고음 (Alert) | 소리를 내거나 경고음을 발생 |
\v | 수직 탭 (Vertical Tab) | 수직 탭 삽입 |
\0 | 널 문자 (Null Character) | 문자열의 끝을 나타냄 |
이때 주의 해야할 점은
printf("\n") 이렇게 큰 따옴표로 묶어야지, printf('\n')로 묶으면 실행되지 않는다.
그리고 \0을 넣으면 문자열의 끝을 나타내기에 문자열 중간에 넣어버리면 나머지들은 포함이 되지 않느다.
에필로그
바로 조건문, 반복문만 하면 2주차 끝
대부분의 코딩은 개인적인생각인데 조건문, 반복문, 입력, 출력만 하면 다 할 수 있다고 생각한다.
'KnockOn' 카테고리의 다른 글
[KnockOn] Linux/Ubuntu C언어 배열 (0) | 2024.11.17 |
---|---|
[KnockOn] Linux/Ubuntu C언어 조건문, 반복문 (2) | 2024.11.15 |
[KnockOn] Linux/Ubuntu C언어 연산자 (0) | 2024.11.13 |
[KnockOn] Linux/Ubuntu C언어 자료형 (0) | 2024.11.12 |
[KnockOn] Linux/Ubuntu C언어 및 컴파일 (0) | 2024.11.11 |