C언어 파일 입출력을 공부해 보았다. 사실 여기는 C보다는 파이썬이 압도적으로 쓰기 편하다. 그치만 나는 C를 사랑하는 전자과다. 예제를 보면서 시작해보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> int main() { FILE *fp; fp = fopen("a.txt", "w"); if (fp == NULL) { printf("error"); return 0; } fputs("hello world!!\n", fp); fclose(fp); return 0; } | cs |
이렇게 예제를 돌리면 될 줄 알았지?? 역시 안된다~~ fopen때문에 warning이 뜬다. 나는 찝찝한 것은 참지 못하기에 fopen_s를 사용하겠다!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> int main() { FILE *fp; errno_t error = fopen_s(&fp, "a.txt", "w"); if (error == 0) { printf("success!! "); } else { printf("error"); return 0; } fputs("hello world!!\n", fp); fclose(fp); return 0; } | cs |
fopen과 fopen_s의 차이를 보이기 위해서 작성한 예제이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> int main() { FILE *fp; errno_t error = fopen_s(&fp, "a.txt", "r"); char arr[20]; if (error == 0) { printf("success!! \n"); } else { printf("error"); return 0; } fgets(arr, 20, fp); printf("arr is %s", arr); fclose(fp); return 0; } | cs |
이건 write 모드로 방금 작성된 파일의 내용을 불러오는 부분이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> int main (){ /* 현재 fp 에 abcdef 가 들어있는 상태*/ FILE *fp; errno_t err = fopen_s(&fp,"a.txt", "r"); fgetc(fp); fgetc(fp); fgetc(fp); fgetc(fp); /* d 까지 입력받았으니 파일 위치 지정자는 이제 e 를 가리키고 있다 */ fseek(fp, 0, SEEK_SET); printf("다시 파일 처음에서 입력 받는다면 : %c \n", fgetc(fp)); fclose(fp); return 0; } | cs |
int fseek ( FILE * stream, long int offset, int origin );
fseek 함수는 fp 를 세번째 인자로 부터 두번째 인자 만큼 떨어진 곳으로 파일 위치 지정자를 돌리는데, 위 경우 SEEK_SET 으로 부터 0 번째 떨어진 곳, 즉 SEEK_SET 으로 돌린다고 볼 수 있다.
이 때 SEEK_SET 은 파일의 맨 처음을 일컫는 매크로 상수. 따라서 위 함수를 통해 fp 의 파일 위치 지정자를 맨 처음으로 돌려서 다시 fgetc 를 하였을 때 a 를 입력받게 된다. 참고로, SEEK_SET 외에도, 현재의 위치를 표시하는 SEEK_CUR 과 파일의 맨 마지막을 표시하는 SEEK_END 상수들이 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int main() { FILE *fp; errno_t err = fopen_s(&fp, "a.txt", "r+"); char data[100]; fgets(data, 100, fp); printf("현재 파일에 있는 내용 : %s \n", data); fseek(fp, 0, SEEK_SET); fputs("hello world is booring", fp); fclose(fp); return 0; } | cs |
+모드는 읽기와 수정을 동시에 할 수 있는 모드이다. 이렇게 하면 처음 위치부터 작성이 되기 때문에 원래 내용들은 모두 지워지게 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <stdio.h> int main() { FILE *fp; errno_t err = fopen_s(&fp, "a.txt", "r+"); //char data[100]; char c; if (err == 0) { printf("success!! \n"); } else { printf("error"); return 0; } while ((c = fgetc(fp)) != EOF) { if (c >= 'A' && c <= 'Z') { fseek(fp, -1, SEEK_CUR); fputc(c + 32, fp); fflush(fp); } else if (c >= 'a' && c <= 'z') { fseek(fp, -1, SEEK_CUR); fputc(c - 32, fp); fflush(fp); } } fclose(fp); return 0; } | cs |
대소문자를 변환해주는 예제이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> #include <string.h> #include <stdlib.h> #define BUFFER_SIZE 20 int main(){ char buffer[BUFFER_SIZE]; FILE *fp; errno_t error = fopen_s(&fp, "a.txt", "r"); if (error != 0) { printf("error"); return; } while (fscanf(fp, "%s", buffer) != EOF) { printf("%s\n", buffer); } return 0; } | cs |
이것도 에러를 뿜뿜 뱉어낸다... 그래서 고쳐 보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> int main() { FILE *fp; errno_t err = fopen_s(&fp, "a.txt", "r+"); char data[100]; //char c; if (err == 0) { printf("success!! \n"); } else { printf("error"); return 0; } while (fscanf_s(fp, "%s", data, 100) != EOF) { printf("%s\n", data); } fclose(fp); return 0; } | cs |
fscanf_s를 정리해 보았다. fscanf_s(스트림 주소, 형식, 입력받을 버터, 버퍼 사이즈) 이렇게 적어놓은 예제이다.
'개발' 카테고리의 다른 글
C 언어 - 두고두고 쓰기 위한 문자열 search 함수 (0) | 2019.01.04 |
---|---|
파이썬 2차원 배열 생성 (0) | 2019.01.02 |
C 언어 if-elseif-else문을 한 줄로! (0) | 2018.12.30 |
C 언어 - linked list를 노드로 구현해 봤다. (0) | 2018.12.28 |
C 언어 문자를 숫자로 & 숫자를 문자로 (0) | 2018.12.28 |