[C] C언어 문자열 나누기 (strtok 사용)
2022. 5. 10. 00:33
(지식)
즉, 최초 초기화 이후 프로그램 종료 시점까지 메모리 공간에 존재하는 전역변수의 특성을 가집니다.
따라서 strtok() 함수를 multi-thread 에서 사용하게 되면 예게치 못한 동작이 발생하게 됩니다.
https://coding-chobo.tistory.com/84
Case 1. 한줄 씩 읽고, 단어 단위로 끊어서 읽기.
소스코드
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
int ch;
char line[1024];
char temp[1024];
char * s;
fp = fopen("file.txt", "r"); // "r" 읽기전용, "w" 쓰기전용
while (!feof(fp)) {
s = fgets(line, sizeof(line), fp); // str = fgets(line, 1024, fp); 도 가능
strcpy(temp, line);
char* ptr = strtok(s, " ");
while(ptr != NULL) {
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
printf("--\n");
}
fclose(fp);
return 0;
}
출력화면
QBC 1 QWE 30 100 -- EWC 2 QWE 30 101 -- CBC 3 QWE 30 102 -- BBC 4 QWE 30 103 -- YBC 5 QMM 30 104 -- -- |
소스코드의 목적
flie.c 파일을 읽기 모드로 열어서 한 바이트를 ch로 읽은 다음 화면으로 출력한다. 그리고 연 파일을 다는다.
#include <stdio.h>
int main()
{
FILE *fp;
int ch;
fp = fopen("aaa", "r");
ch = fgetc(fp);
fputc(ch, stdout);
fclose(fp);
return 0;
}
아래는 위의 소스코드에 대한 설명입니다.
#inlcude <studio.h>
// flie.c 파일을 읽기 모드로 열어서 한 바이트를 ch로 읽은 다음 화면으로 출력한다
// 그리고 연 파일을 다는다.
int main()
{
FILE *fp;
int ch;
fp = fopen("aaa", "r"); // "r" 읽기전용, "w" 쓰기전용
ch = fgetc(fp);
fputc(ch, stdout);
fclose(fp);
return 0;
// 화면에 한바이트가 찍히게 되어있음
fopen: 파일을 연다. 모드는 지정
fgetc: 파일에서 1byte를 읽는다.
fputc: 1byte를 표준출력으로 보낸다.
fclose: 파일을 닫음으로 자원을 해지한다.
}
컴파일 절차 / 실행화면
$ vi aaa
(hello 입력)
$ gcc file_1.c
$ ./a.out
$ cat aaa
출력결과:
h
소스코드의 목적
한문장 읽는 역할하는 소스코드
#include <stdio.h>
int main()
{
FILE *fp;
int ch;
fp = fopen("aaa", "r");
while((ch = fgetc(fp)) != EOF)
fputc(ch, stdout);
fclose(fp);
return 0;
}
컴파일 절차 / 실행화면
$ gcc file_2.c
$ ./a.out
$ cat aaa
출력결과:
hello
(cat과 같은 역할을 하는 소스코드)
EOF는 파일의 끝 이건 #define EOF (-1)로 되어있습니다. -1은 아스키코드가 아니라서 파일끝을 구분하기 위해 쓰입니다.
0a는 '\n'임 하드리턴.
주로 쓰는 변환하는 법 (#아스키코드 변환, #아스키코드, #숫자변환)
대문자 아스키코드로 변환 : 'a' -32 대문자 아스키코드로 변환 : 'A'+32 아스키숫자를 실제 숫자 변환 : '7' - '0' |
필수 ASCII 코드
'a' => 97 = 0x61 'A' => 68 = 0x44 '0' => 48 = 0x30 '\n' => 10 = 0x0A (하드리턴) '\r' => 13 = 0x0D ' ' => 32 = 0x20 '\t' = 9 '\0' = 0 (부연설명) '\r' 캐리지 리턴 : 커서를 맨 앞에 보내는거 (윈도우하고 맥만 씀) |
fgetc 리턴값이 int인 경우
Q. 왜 이 함수의 리턴값이 int일까?
A. 표준 라이브러리 개발자의 표준을 따르기 위해.
( 만약 이걸 어기면 형변환 때문에 심각한 오류가 발생할 수 있다. (예를 들어 char로 하면 오류로 EOF로 간주될 수 있따))
$ wc -c aaa를 치면
출력결과: 6 aaa
파일의 바이트 수가 표시가 됩니다. 여기서 얻을 수 있는 사실은 파일의 데이터에는 EOF가 없다는 것이입니다.
EOF에 대한 고찰
요약 : EOF는 파일 속에 있는 값이 아니라! Library가 리턴하는 값입니다.
이미 파일의 inode 구조체 속에 파일사이즈가 있습니다. 파일의 읽은 바이트 수를 파일의 사이즈랑 비교해보면 알 수 있습니다. 그래서 파일의 끝에다가 EOF를 넣을 필요가 없습니다.
즉 파일 사이즈 까지 읽으면 파일을 끝까지 읽었다고 생각하는 것이다. 즉 그래서 EOF를 파일의 끝에다가 집어넣을 필요가 없습니다.
파일의 끝은 구분자가 따로 없습니다. 파일의 정보 구조체에 이미 파일의 크기가 기록되어 있으므로 시스템은 파일을 끝까지 읽었는 지를 구분할 수 있습니다.
EOF는 4byte 전체가 1로 채워진 int 타입의 -1입니다. 그냥 리턴해주는 4byte 값입니다. 라이브러리가 리턴해주는.
즉, EOF는 파일 속에 있는 값이 아니라! Library가 리턴하는 값입니다.
fgetc의 리턴값은 int로 받아야합니다. 파일의 중간의 ff패턴은 -1로 해석되지 않기 위함입니다.
꼭 기억할 건 EOF는 -1이고 파일의 속에 들어있는 값이 아니라 리턴하는 값이다. 그 값은 인티저에 넣어야한다.
새로 알게된 명령어
파일의 사이즈 측정
$ wc -c aaa
헥사덤프를 씀
$ xxd aaa
'C > Code snippet' 카테고리의 다른 글
[C] 나만의 utils 만들기 (0) | 2022.05.18 |
---|---|
[Linux/C] strcat 사용시 주의사항 (0) | 2022.05.14 |
[C] SA_SIGINFO 예제 (0) | 2022.05.09 |
[C] sleep 함수로 2초마다 printf 찍게 하기 (리눅스 C) (0) | 2022.05.05 |
[C] 파일 읽기 간단한 예제 (0) | 2022.05.02 |