Unix I/O vs Standard I/O
Standard I/O models open files as streams
-> Abstraction for a file descriptor and a buffer in a memory
Unix file I/O
-> open(), read(), write(), close(), ...
-> A uniform way to access files, I/O devices, network sockets, kernel data structures, Etc.
When to use standard I/O
-> When working with disk or terminal files
When to use raw Unix I/O
-> When you need to fetch file metadata
-> When you read or write network sockets or pipes
-> In rare cases when you need absolute highest performance
Word Search Program
find every target word and print the line number
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
void itoa(int fd, int x)
{
char buf[6];
buf[5] = '\n';
int target = x;
int length = 5;
while(target){
char tmp = (target % 10) + '0';
buf[--length] = tmp;
target /= 10;
}
write(fd, buf + length, 6 - length);
}
int main(int argc, char **argv)
{
int fd1, fd2; //file descriptor
int retval1, retval2; //return value
char buf; //buffer
int nbytes; //number of bytes read
char target[11]; //target word
if ((fd1 = open("peterpan.txt", O_RDONLY)) < 0){
perror("open");
exit(1);
}
if ((fd2 = open("result.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666)) < 0){
perror("open");
exit(1);
} //files open
int len = 0;
while(nbytes = read(0, &buf, 1)){ //0=stdin, 1=stdout, 2=stderr
if(nbytes <= 0) break;
if(buf == '\n') break;
else{
target[len] = buf;
len++;
}
} //get target word
int line = 1;
int idx = 0;
while(read(fd1, &buf, 1) > 0){
if(buf == '\n'){
line++;
}
if(buf == target[idx]){
idx++;
if (idx == len){
itoa(fd2, line);
lseek(fd1, -idx+1, SEEK_CUR);
idx = 0;
}
}
else{
lseek(fd1, -idx, SEEK_CUR);
idx = 0;
}
} //find target word in peterpan.txt & write the line in result.txt
//have to make itoa function
//use lseek function
if((retval1 = close(fd1)) < 0){
perror("close");
exit(1);
}
if((retval2 = close(fd2)) < 0){
perror("close");
exit(1);
} //files close
}
itoa()
-> file descriptor, integer형 변수를 parameters로 받고, 바로 file에 변환된 char형 변수를 입력
peterpan.txt를 한 글자 씩 read()하는 while문 내부에서,
개행문자인 경우 line++;
1) buf == target[idx]인 경우 idx를 1 증가시킴
2) idx = len인 경우 (target word와 일치하는 경우) 바로 result.txt에 line을 입력해주고, lseek() & idx 초기화 (+ aaaa일 때 target이 aaa인 경우 두번 일치하므로 -idx + 1만큼 앞으로 seek pointer를 이동시켜야함)
2) 그렇지 않은 경우 -idx만큼 앞으로 seek pointer를 이동시키고 idx 초기화