파일입출력 해당 행 수정( 거의 다 된거같은데 ㅠㅠ)

익명 사용자의 이미지

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <errno.h>  
#include <string.h> 
struct card { 
    char name[20]; 
    char company[20]; 
    char tel[20]; 
}card; 
main() 
{ 
    char ch; 
    char name[10]; 
    off_t size; 
    char buffer[512]; 
    char update[512]; 
    char test[512]; 
    int i=0,i2=0; 
    int fd; 
    ssize_t nread; 
 
    fd=open("memo.txt",O_RDWR); 
 
    printf("name : "); 
    scanf("%s",name); 
 
    printf("up name : "); 
    scanf("%s",&card.name); 
    printf("up company : "); 
    scanf("%s",&card.company); 
    printf("up tel : "); 
    scanf("%s",&card.tel); 
    sprintf(update,"%s\t%s\t\t%s\n",card.name,card.company,card.tel); 
    printf("\n\n"); 
    while((nread=read(fd,&ch,1))>0) 
    { 
           if(ch=='\n') 
           { 
                  buffer[i++]=ch; 
                  if(!strncmp(buffer,name,strlen(name))) 
                  { 
                             lseek(fd,strlen(buffer)-1,SEEK_SET); 
                             write(fd,update,strlen(update)); 
                             printf("on : %s",buffer); 
                             i=0; 
                  }else 
                  { 
                             i=0; 
                  } 
              }else{ 
                  buffer[i++]=ch; 
           } 
 
    } 
} 

보시면 리눅스환경에서 저수준 파일입출력을 통해
원하는 행을 수정하는 프로그램입니다.

kim a 101
park b 202
cc c 303

문제가 생기는게 이렇게 입력되있으면
park의 행을 수정하려고 하는데.

park b 202 <--여기 문자열의 길이가 10이라고 치죠
park bbb 2222 <--새로입력 받은 값입니다. 이렇게 문자열을 기존 문자열(10) 보다 크면
c 303 파일이 깨져버립니다. cc의 공간까지 문자열을 먹으면서
파일을 쓰는거가타요

이걸 어떻게 해결하나요 ㅠㅠ

익명 사용자의 이미지

어.. 위에 본문내용이 제대로 안써져있네요
kim a 101
park b 202
cc c 303

park을 수젖ㅇ하면

kim a 101
lee elelel eellel
303

등.. 이렇게 깨지네요..
너무 모자라도 깨지고 넘쳐도 깨지네요 ㅎ..

 의 이미지

워드프로세서 쓰듯 중간에서 편집하더라도 뒷 내용이 알아서 당겨지거나 밀어질 줄 아셨나요?
그것은 워드프로세서가 그런 기능을 특별히 구현하였기 때문이지 메모리나 디스크가 자동으로 그렇게 해주는 게 아니죠.
파일 I/O는 주어진 위치에서부터 시작하여 주어진 데이터를 그대로 덮어씌우기만 할 뿐, 워드프로세서 같은 고급 기능은 제공하지 않습니다.

그런 기능을 구현하기 위한 방법은 여러 가지 있겠습니다만(파일 내용을 전부 메모리로 불러들여서 임의 위치에 삽입/삭제가 가능한 자료구조를 구성한다던지, 파일을 아예 새로 열어서 편집된 데이터를 따로 기록한다던지 등) 아무튼 현재의 구현은 바라시는 바와 상당히 동떨어져 있는 것 같네요.

익명 사용자의 이미지

헐... 다 엎어야 된다는 소리인가요 ㅠㅠ
read와 lseek를 이용해서 수정하려고 하는데
어렵네요 ..

ymir의 이미지

memo.txt 가 "%s\t%s\t\t%s\n" 와 같이 하나의 라인이 레코드 하나를 가리킨다면..
임시 파일을 생성해서 라인 단위로 복사하면서, 원하는 라인만 새로 고쳐서 저장하세요.

while (fget(buffer, sizeof(buffer), fp))
{
    if (!strncmp(buffer, name, strlen(name)) && buffer[strlen(name)] == '\t')
        fputs(update, new_fp);
    else
        fputs(buffer, new_fp);
}

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』