-
C/C++ read 함수 - 파일을 읽는 함수C,C++ & Linux 2020. 4. 22. 01:28728x90
read(2) 함수 기능
파일을 읽는 함수입니다.
함수 원형
#include <unistd.h> ssize_t read(int fd, void *buf, size_t nbytes);
매개변수
int fd
읽을 파일의 파일 디스크립터
void *buf
읽어들인 데이터를 저장할 버퍼(배열)
size_t nbytes
읽어들일 데이터의 최대 길이 (buf의 길이보다 길어선 안됨)
반환값
읽어들인 데이터의 길이
무조건 nbytes 가 리턴되는 것은 아님. 중간에 파일의 끝을 만난다면 거기까지만 읽기 때문
예제
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include "ssu_employee.h" int main(int argc, char *argv[]) { struct ssu_employee record; int fd; int record_num; if (argc < 2) { fprintf(stderr, "Usage : %s file\n", argv[0]); exit(1); } // 입력받은 파일을 읽기모드로 열기 if ((fd = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "open error for %s\n", argv[1]); exit(1); } while (1) { printf("Enter record number : "); scanf("%d", &record_num); // 음수 레코드 번호 입력 시 종료 if (record_num < 0) break; // record_num 번째 레코드에 접근 if (lseek(fd, (long) record_num * sizeof(record), 0) < 0) { fprintf(stderr, "lseek error\n"); exit(1); } // record_num 번째 레코드의 시작부분에서부터 record 사이즈만큼 읽음 // 이는 곧 record_num 번째 레코드를 읽어들여 record 변수에 저장함을 의미 if (read(fd, (char *) &record, sizeof(record)) > 0) printf("Employee : %s Salary : %d\n", record.name, record.salary); else printf("Record %d not found\n", record_num); } close(fd); exit(0); }
레코드 생성하는 코드는 write 에 있습니다.
<ssu_test.txt> Linux System Programming! Unix System Programming! Linux Mania Unix Mania <main.c> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #define BUFFER_SIZE 1024 int main(int argc, char *argv[]) { char buf[BUFFER_SIZE]; char *fname = "ssu_test.txt"; int count; int fd1, fd2; fd1 = open(fname, O_RDONLY, 0644); fd2 = open(fname, O_RDONLY, 0644); if (fd1 < 0 || fd2 < 0) { fprintf(stderr, "open error for %s\n", fname); exit(1); } // Linux System Programming! 읽어들여서 buf에 저장 // 이 때 널문자'\0' 는 buf에 없음 count = read(fd1, buf, 25); // 따라서 이 구문이 없으면 뒷 쪽의 쓰레기 값들이 %s 를 통해 출력됨 buf[count] = 0; printf("fd1's first printf : %s\n", buf); // 줄바꿈을 읽지 않기 위해 seek position 1칸 이동 lseek(fd1, 1, SEEK_CUR); // Unix System Programming! 읽어서 buf에 저장 count = read(fd1, buf, 24); buf[count] = 0; printf("fd1's second printf : %s\n", buf); // 여기서부터는 fd2 를 읽는데 // fd1 을 아무리 읽고 써도 fd2의 seek position 에는 변화가 없으므로 // fd2 의 seek position 은 파일의 맨 앞에 있음 count = read(fd2, buf, 25); buf[count] = 0; printf("fd2's first printf : %s\n", buf); lseek(fd2, 1, SEEK_CUR); count = read(fd2, buf, 24); buf[count] = 0; printf("fd2's second printf : %s\n", buf); exit(0); }
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char *argv[]) { int fd; char c; if ((fd = open("ssu_test.txt", O_RDONLY)) < 0) { fprintf(stderr, "open error for %s\n", "ssu_test.txt"); exit(1); } while (1) { // 모든 글자를 한 글자씩 읽어들임 // 파일에 끝에 도달하여 읽지 못하는 순간 -1 리턴되어 끝남 if (read(fd, &c, 1) > 0) putchar(c); else break; } exit(0); }
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #define TABLE_SIZE 128 #define BUFFER_SIZE 1024 int main(int argc, char *argv[]) { static struct { long offset; // 데이터가 시작하는 위치 int length; // 데이터의 총 길이 } table[TABLE_SIZE]; char buf[BUFFER_SIZE]; long offset; int entry; int i; int length; int fd; if (argc < 2) { fprintf(stderr, "usage: %s <file>\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "open error for %s\n", argv[1]); exit(1); } entry = 0; offset = 0; // 파일을 끝까지 읽음 while ((length = read(fd, buf, BUFFER_SIZE)) > 0) { // 매 글자 체크 for (int i = 0; i < length; i++) { table[entry].length++; offset++; // 개행문자가 발견되면 table 의 다음번(entry에 offset을 저장) if (buf[i] == '\n') table[++entry].offset = offset; } } //for (i = 0; i < entry; i++) // printf("%d : %ld, %d\n", i + 1, table[i].offset, table[i].length); while (1) { printf("Enter line number : "); scanf("%d", &length); if (--length < 0) break; // table[length].offset 에는 length 번째 줄이 파일의 몇 바이트 부분에서 시작되는지 저장되어 있으므로 // 해당 위치로 찾아가서 lseek(fd, table[length].offset, 0); // table[length].length 만큼 읽으면 length 번째 줄을 다 읽게됨 if (read(fd, buf, table[length].length) <= 0) continue; buf[table[length].length] = '\0'; printf("%s", buf); } close(fd); exit(0); }
리눅스시스템프로그래밍 저자 : 홍지만
https://book.naver.com/bookdb/book_detail.nhn?bid=14623672
책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)'C,C++ & Linux' 카테고리의 다른 글
C/C++ write() (0) 2020.05.14 C/C++ close() 함수 (0) 2020.05.14 C/C++ lseek 함수 - 파일 커서(seek pointer) 조정 (0) 2020.04.22 C/C++ creat 함수 - 파일 생성 (0) 2020.04.21 C/C++ open 함수 - 파일 생성 / 읽기 / 쓰기 (0) 2020.04.21