본문 바로가기
컴퓨터 기초/운영체제 실습

c언어 문자 치환 - 특정 문자 찾아서 바꾸기

by 인생여희 2021. 1. 8.

c언어 문자 치환 - 특정 문자 찾아서 바꾸기

 

 

5-1. c언어 파일입출력 함수를 이용해서 파일의 단어수 체크하기(응용예제)

5-2. c언어 파일함수로 특정 문자 찾기(응용예제)

 

 

이전 포스팅에서 c언어 파일,문자함수를 이용해서 특정 단어수를 체크해서 출력하고, 특정 문자가 포함되어 있는 열을 찾아서 출력해주는 예제를 살펴보았다. 이번에는 c언어 함수를 이용해서 파일에서 문자를 치환하는 예제를 살펴보려고 한다. 예를들어 파일 여러 줄에 hi 라는 단어가 있다면 전부 찾아서 hello 로 변경해주는 예제이다.

 

c 파일을 컴파일 한 뒤 실행파일명 문자치환을할 파일명 치환할대상문자 치환문자 순으로 입력하면 된다.

 

예) ./searchword.o log caa can

 

searchword.o 실행파일에서 log 파일을 읽어서 caa 라는 단어를 찾아서 can으로 변경해주는 명령어다.

 

 

c언어 문자 치환 예제

 

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
#include "fcntl.h"


int main(int argc, char * argv[]){
    
    //읽기전용 파일 기술자
    FILE *fdr = NULL;
    
    //쓰기전용 파일 기술자
    FILE *fdw = NULL;
    
    //단어수
    unsigned int wordCount = 0;
    
    //라인 수
    unsigned int lineNumber = 0;
    
    //찾을 문자열
    char *searchword;
    
    //바꿀 문자열
    char *changeword;
    
    //파일에서 읽을 바이트
    char buf[1024];
    char *readByte;
    
    char *fileName;
    
    if (argc != 4) {
        perror("인자 개수를 확인해 주세요. : ./searchfile filename searchword changeword\n");
        exit(0);
    }
    
    //파일 이름
    fileName = argv[1];
    
    //찾을 문자열
    searchword = argv[2];
    
    //변경할 문자열
    changeword = argv[3];
    
    
    printf("찾을 문자열 : %s , 변경할 문자열 : %s \n" ,searchword , changeword );
    
    //1.access() 함수는 프로세스가 지정한 파일이 존재하는지, 읽거나 쓰거나 실행이 가능한 지를 확인하는 함수
    //파일 접근가능 체크 - 존재 : 0, 존재안함 : -1
    int resultNum = access(fileName , F_OK);
    
    printf("접근 체크 결과 : %d\n\n" , resultNum);
    
    
    if (resultNum == -1) {
        
        //오류 출력함수
        perror("파일 접근 실패\n");
        
        exit(0);
    }
    
    
    //2.파일 기술자 열기
    fdr =  fopen(fileName , "r");

    if (fdr == NULL) {
        perror("읽기전용 파일 기술자 열기 실패\n");
        exit(0);
    }
    
    
    //2-1. 쓰기전용 파일 기술자 열기
    fdw = fopen("log2" , "w+");
    if (fdw == NULL) {
        perror("쓰기전용 파일 기술자 열기 실패\n");
        exit(0);
    }

    //3.파일의 끝이면 1, 끝이 아니면 0을 반환
    while (feof(fdr) == 0) {
        
        //라인 수 증가
        lineNumber += 1;
        
        
        /*
             #.참고
             fgets() 함수는 scanf()나 gets()와는 달리 뒤에 개행문자가 붙는다.
             그 개행문자를 제거하려면 다음과 같이 하면 된다.
             fgets(str, strlen(str), stdin);
             str[strlen(str) - 1] = '\0';
         */
        
        //4.한줄읽기
        readByte = fgets(buf, sizeof(buf) , fdr);
        
        buf[strlen(buf) -1] = '\0';
        
        //5.복사를 위한 임시 문자열
        char *tempStr1 = malloc(sizeof(char) * 1024);
        

        //6.읽은 한 줄을 " " 기준으로 하나씩 자르기
        char *ptr = strtok(buf, " ");
        
        //7.
        while (ptr != NULL) {
            
            //자른 단어를 하나씩 비교
            int ret = strncmp(searchword , ptr , 1);
            
            //두 단어가 같다.
            if (ret == 0) {
                
                //찾은 단어수 + 1
                wordCount += 1;
                
                strcat(tempStr1, changeword);       // tempStr 뒤에 changeword을 붙임
                
            }else{
            
                // tempStr 뒤에 자른 단어를 붙임
                strcat(tempStr1, ptr);
                
            }
            
            strcat(tempStr1, " "); // "한칸 띄우기"
            ptr = strtok(NULL, " "); //다음 문자열을 잘라서 포인터를 반환
            
        }
        
        //개행
        strcat(tempStr1, "\n");
    
        
        //파일에서 읽은 줄이 있으면 - 치환된 단어가 포함된 문자열 출력
        if (readByte != NULL) {
            
            printf("%s" , tempStr1);
            //파일에 쓰기
            
            fputs(tempStr1, fdw);
        }
        
        //위에서 할당한 임시 복사 포인터 문자열 해제
        tempStr1 = NULL;
        free(tempStr1);
        
    }
    
    
    printf("\n**결과**\n파일: %s \n%s => %s 로변경\n개수 총 %d 개\n" , fileName, searchword ,changeword , wordCount);
   

    
    //읽기 전용 파일 닫기
    int closeResult = fclose(fdr);
    printf("\n파일 닫기 체크 : %d \n" , closeResult );
    
    //파일 닫기 체크
    if(closeResult < 0){
        perror("파일 닫기 실패");
        exit(0);
    }
    
    
    //쓰기 전용 파일 닫기
    int closeFdwResult = fclose(fdw);
    printf("\ncloseFdwResult 파일 닫기 체크 : %d \n" , closeFdwResult );
    
    //파일 닫기 체크
    if(closeFdwResult < 0){
        perror("파일 닫기 실패");
        exit(0);
    }
    
    return 0;
    
}

 

 

위의 예제를 실행하면 아래와 같은 결과가 나온다.

log 파일에는 I caa do yes we caa 이 여러 줄에 걸쳐서 저장되어 있다.

명령어를 실행하면 caa를 can으로 변경한 뒤, 결과를 출력하고 log2 라는 파일을 생성해서 문자치환한 내용을 전부 저장한다. 

 

찾을 문자열 : caa , 변경할 문자열 : can 
접근 체크 결과 : 0

I can do 
yes we can 
I can do 
yes we can 
I can do 

**결과**
파일: log 
caa => can 로변경
개수 총 5 개

파일 닫기 체크 : 0 

closeFdwResult 파일 닫기 체크 : 0 

 

log 파일 내용

 

더보기

I caa do 
yes we caa 
I caa do 
yes we caa 
I caa do 

 

 

이번 포스팅은 아래 포스팅와 이어지는 내용이라서 참고하면 도움이 될 것같다.

 

5-1. c언어 파일입출력 함수를 이용해서 파일의 단어수 체크하기(응용예제)

5-2. c언어 파일함수로 특정 문자 찾기(응용예제)