C 문자열
C언어 문자열과 관련한 내용을 정리한다
스트림
. 스트림(Stream)은 특정한 프로그래밍 언어 및 운영체제에서 컴퓨터 프로그램과 구동 환경 간에 미리 연결된 일종의 입출력을 위한 통로
1
2
3
stdin 표준 입력 스트림 키보드 대상 입력
stdout 표준 출력 스트림 모니터 대상 출력
stdeer 표준 에러 스트림 모니터 대상 출력
. 해당 스트림은 프로그램 시작과 동시에 자동으로 형성되고, 종료 시 자동으로 삭제 됨
문자 단위 입출력
1
2
3
4
5
6
7
8
9
...
// 하나의 문자 출력
int putchar(int a); // 인자로 전달된 단일 문자 모니터에 출력
int fputc(int a, FILE * stream); // FILE * stream을 통해 출력 대상 지정 가능
// 하나의 문자 입력
int getchar(void); // 키보드로 입력된 단일 문자 반환
int fgetc(FILE * stream); // 문자를 입력 받을 대상정보 인자로 전달
...
. 함수 호출 실패 시 EOF 반환 (입력의 경우, 파일의 끝에 도달하여도 EOF 반환)
EOF (End of File)
. 파일의 끝을 표헌하기 위해 정의해 놓은 상수, int형 데이터로 -1
. EOF 반환을 putchar, fputc, getchar, fgetc 에서 파악하기 위해 반환형을 int
로 지정함
. 함수 호출이 실패하였을 때, 파일의 끝에 도달하였을 때, 윈도우에서 CTRL + Z, 리눅스에서 CTRL + D 입력 시 발생
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main(void)
{
int ch;
while(1){ // 입력된 문자는 EOF를 만날 때 까지 버퍼에 유지
ch = getchar();
if(ch == EOF)
break;
putchar(ch);
}
return 0;
}
문자열 단위 입출력
1
2
3
4
5
6
7
8
...
// 문자열 출력
int puts(const char * s); // 자동 개행
int fputs(const char * s, FILE * stream); // 자동 개행 없음, 출력 대상 지정 가능
// fputs의 사용
fputs(str, stdout); printf("\n"); // 자동 개행이 없기 때문에, 강제 개행 필요
...
. 함수 호출 성공 시 0
반환, 실패 시 EOF
반환
1
2
3
4
5
6
7
8
9
10
11
12
...
// 문자열 입력
char * gets(char * s); // 메모리 오버플로어 문제가 발생할 수 있음
char * fgets(char * s, int n, FILE * stream); // n -> 일반적으로 sizeof(type)-1만큼 입력
// 사용 방법
char str[10];
gets(str);
fgets(str, sizeof(str), stdin); // 공백, 엔터 입력도 문자열로 받아들이고 저장
while(getchar() != '\n'); // 버퍼 비움 !? 맞는지 확인 필요
...
. 파일 끝에 도달 or 함수 호출 실패 시 NULL
포인터 반환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
int main(void)
{
char str[10];
int i;
for(i=0; i < 2; i++)
{
fgets(str, sizeof(str), stdin);
printf("Read %d: %s \n", i+1, str);
}
return 0;
}
. 출력 결과를 보면, 개행이 두 번 이루어짐
. 이는 입력 시의 Enter \n
가 문자열에 포함되고, fgets 함수의 동작으로 인해 입력 문자열에 자동으로 개행문자가 삽입되었기 때문
표준 입출력 버퍼
1
2
3
4
5
6
7
...
int fflush(FILE * stream); // 출력 버퍼를 지움
// 출력 버퍼에 저장된 데이터를 목적지로 전송함
while(getchar() != '\n'); // 입력 버퍼를 비우기 위한 명령
// 일반적으로 함수로 구성
...
. 함수 호출 성공 시 0
, 실패 시 EOF
반환
. 입력 버퍼의 경우, 버퍼를 비우면 데이터가 소멸됨
기타 함수
문자열 길이 반환
. NULL 값을 발견할 때 까지, 문자를 카운팅함
1
2
3
4
5
#include <string.h>
...
// typedef unsigned int size_t;
size_t strlen(const char * s);
...
문자열 복사
1
2
3
4
5
#include <string.h>
...
char * strcpy(char * dest, const char * src);
char * strncpy(char * dest, const char * src, size_t n);
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "1234567890";
char str2[20];
char str3[5];
strcpy(str2, str1); // 두 배열의 크기가 동일해야 함
puts(str2);
/** error case **/
strncpy(str3, str1, sizeof(str3)); // strncpy는 Null값 관계 없이 복사
// NULL 값의 유무 판단 안함, 단순 복사
puts(str3);
strncpy(str3, str1, sizeof(str3)-1); // NULL 값 위한 공간 확보
str3[sizeof(str3)-1] = 0; // NULL 값 대입
puts(str3);
return 0;
}
. error case
에서 str1에서 str3의 복사시, NULL 값의 유무와 관계 없이 데이터 단순 복사
. 따라서, str3을 출력 시, 문자열의 끝인 NULL값을 찾지 못하여, 쓰레기 값 출력
문자열 붙이기
1
2
3
4
5
#include <string.h>
...
char * strcat(char * dest, const char * src);
char * strncat(char * dest, const char * src, size_t n); // 자동 NULL 값 삽입
...
문자열 비교
1
2
3
4
5
6
7
8
9
#include <string.h>
...
// s1 > s2 == +
// s1 < s2 == -
// s1 == s2 == 0
int strcmp(const char * s1, const char * s2);
int strncmp(const char * s1, const char * s2, size_t n);
...
문자열 형변환
1
2
3
4
5
6
#include <stdlib.h>
...
int atoi(const char * str); // 문자열 -> int 형
int atol(const char * str); // 문자열 -> long 형
int atof(const char * str); // 문자열 -> double 형
...