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

익명 사용자의 이미지

#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 』

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.