C언어 파일 수정 문제

조회수 3092회

내용이 이미 작성된 텍스트 파일에서 "yoons" 라는 문자열의 위치를 알아내고,

'y' 대신 'h'로 수정하려는 의도를 가진 소스를 작성했는데요.

파일을 "rt" 모드로 읽어서 "yoons"를 검색하여 y의 파일내의 위치를 알아내고,

"rt" 모드 스트림을 종료하고, 같은 파일을 "at" 모드로 스트림을 열고 fseek로 파일내의 'y'위치를 지시한 뒤,

fputc('h',write_data); 를 통해 y에 위치에 h를 입력함으로써 y를 수정하려고 하는데,

항상 파일끝단으로 위치가 이동되면서 파일의 끝부분에 자동적으로 h가 작성됩니다.

첨부한 사진파일에서 15가 y의 위치고 43이 파일의 제일 끝 위치입니다.

분명 위치 지시자를 통해서 파일의 위치를 지정하고 fputc를 통해 단어를 입력했는데,

끝단으로 다시 이동해서 덧붙이는 이유와 이를 해결할 수 있을만한 도움되는 함수나 해결책

부탁드리겠습니다.

이미지

소스

define _CRT_SECURE_NO_WARNINGS

include

include

include

include

void Display() {

system("cls");

printf("***** MENU *****\n");
printf("1. Insert\n");
printf("2. Delete\n");
printf("3. Search\n");
printf("4. Print All\n");
printf("5. Exit\n");
printf("Choose the item : ");

}

void Deco_Display(int ch) {

switch(ch)
{
case 1 : printf("[ INSERT ] \n"); break;
    case 2 : printf("[ DELETE ] \n"); break;
        case 3 : printf("[ SEARCH ] \n"); break;
            case 4 : printf("[ PRINT ALL DATA ] \n"); break;
                case 5 : printf("Exit The Program...\n\n");return;
}

}

typedef struct datafile {

char name[15];
char number[15];

}DF;

void Insert() {

FILE * write_data = fopen("data.txt","at");
DF in_value;
char cut_ch = ' ';
char str_ch = '\n';

printf("Input Name : ");
scanf(" %s",in_value.name);

printf("Input Tel Number : ");
scanf(" %s",in_value.number);

fputc(cut_ch,write_data);
fputs(in_value.name,write_data);
fputc(cut_ch,write_data);
fputs(in_value.number,write_data);


printf("\n      Data Inserted\n");

fclose(write_data);

}

void Printdata() { FILE * read_data = fopen("data.txt","rt");

char name[15];
char number[15];


while(feof(read_data)==0)
{
    fscanf(read_data,"%s %s",name,number);
    printf("Name : %s Tel: %s \n\n",name,number);

}

fclose(read_data);

}

void Search() {

FILE * read_data = fopen("data.txt","at");
char s_name[15]; // 검색할 이름
char data_name[15]; // 파일에서 비교대상 추출 문장
char data_number[15];

fseek(read_data,0,SEEK_SET); // 검색 위치를 처음으로 초기화

printf("Search Name : ");
scanf("%s",s_name); // 검색할 대상의 이름 입력


while(1)
{
    fscanf(read_data,"%s %s",data_name,data_number);
    if(strcmp(s_name,data_name)==0) // data를 읽어와 입력문장과 비교
    {
        printf("\n\nName : %s Tel: %s \n\n",data_name,data_number);
        break;
    }

    if(feof(read_data)!=0) // 파일의 끝에 도달했을때
    {
        printf("검색한 데이터가 존재하지 않습니다...\n\n");
        break;
    }

}

fclose(read_data);

}

void Delete() {

char s_name[15];
char data_name[15];
char t_name[15];
char t_number[15];
char temp[250]= " ";
char jump[2] = " ";
char d_flag = 0;

char i = 0;
int str_num = 0;
long pos = 0;

FILE * read_data = fopen("data.txt","rt");
FILE * write_data = fopen("data.txt","a+t");
fseek(read_data,0,SEEK_SET);

printf("Search Name : ");
scanf("%s",s_name); // 검색할 대상의 이름 입력

for(i=0;i<15;i++) // 검색 대상의 이름 길이 계산 FOR 문
{
    if(s_name[i]=='\0')  
    {
        str_num = i;
        break;
    }
}


while(1)
{
    fscanf(read_data,"%s",data_name);

    if(strcmp(s_name,data_name)==0)
    {
        fseek(read_data,-(str_num),SEEK_CUR);
        pos = ftell(read_data);

        fscanf(read_data,"%s %s",t_name,t_number); // 삭제할 문장 

        while(feof(read_data)==0)
        {
            fscanf(read_data,"%s %s",t_name,t_number);

            strcat(temp,t_name);
            strcat(temp,jump);
            strcat(temp,t_number);
            strcat(temp,jump);

        }
        fclose(read_data); // 읽기 종료
        d_flag = 1;

        printf("\n위치조정 POS : %d\n",pos);
        fseek(write_data,pos,SEEK_SET);

        fputc('h',write_data);
        printf("\n문자 입력후 위치 POS : %d\n",ftell(write_data));
        fclose(write_data);

        break;

    }


    if(feof(read_data)!=0) // 파일의 끝에 도달했을때
    {
        printf("검색한 데이터가 존재하지 않습니다...\n\n");
        break;
    }
}
if(d_flag==0) fclose(read_data);

} void main() {

//FILE * read_data = fopen("data.txt","rt");
//FILE * write_data = fopen("data.txt","wt");

int choice = 0;

while(1)
{
    Display(); // 기본 메뉴 구성 및 화면 클리어 

    scanf(" %d",&choice); // 메뉴 선택
    getchar(); // 입력 버퍼 클리어

    Deco_Display(choice); 

    switch(choice)
    {
    case 1 : Insert(); break;
    case 2 : Delete(); break;
    case 3 : Search(); break;
    case 4 : Printdata(); break;
    case 5 : return;
    }
    system("pause");
}
return;

}

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • write file을 a+ 모드로 open 했기 때문에 output operations이 모두 end of file부터 실행되게 됩니다. (a 모드도 마찬가지 입니다)

    참고: URL

    append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 그냥 a모드로 오픈하면 중간부터 문자 출력이 가능하다는 말씀이신가요? 알 수 없는 사용자 2019.1.17 12:47
    • a / a+ 모드 다 마찬가지입니다. 알 수 없는 사용자 2019.1.17 13:41
    • 원하시는 동작은 r+ 모드로 open 하시면 되겠네요 (read/update: Open a file for update (both for input and output). The file must exist.) 알 수 없는 사용자 2019.1.17 13:43
    • 감사합니다! 문제도 해결하고 앞으로도 도움될 만한 사이트도 알려주셔서 너무 도움이 되었습니다. 알 수 없는 사용자 2019.1.17 21:27

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)