(C++) 문자열 첫 번째 NULL

조회수 658회

문자열을 공백 단위로 입력받아 각 문자열에서 문장 부호를 제거하는 프로그램을 작성 중입니다. 이 과정에서 "컴퓨터"같은 문자열에서 문장부호를 NULL로 바꾸어서 제거하면 첫번째 문자가 NULL이 되어 버려 아예 문자열 자체가 출력이 되질 않습니다. '그대'의 같은 놈들은 그대 이렇게만 나오고요. 이를 해결할 수 있는 방법이 있을까요?

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>

#define R 1001
using namespace std;

char word[R]; // 텍스트파일에서 문자를 받아오는 변수입니다.
char WordDataSet[R][R]; // 받은 데이터를 담고있는 2차원 배열입니다.

int main() {

    FILE* f = fopen("input.txt", "r"); // 파일을 읽기 형식으로 받아줍니다. 

    if (f == NULL) printf("None file\n"); // 파일이 존재하지 않을 경우 예외처리입니다.
    int i = 0; //  받은 데이터들의 인덱스를 표시하는 변수입니다.

    while (!feof(f)) {
        fscanf(f, "%s", WordDataSet[i]); // 텍스트파일에서 문자열을 받습니다.
        int size = strlen(WordDataSet[i]); //  텍스트파일에 있는 문자열의 길이를 구합니다.
        for (int k = 0; k < size; k++) {
            if (WordDataSet[i][k] >= 33 && WordDataSet[i][k] <= 47) {
                /*if (WordDataSet[i][k + 1] >= 44032 && WordDataSet[i][k + 1] <= 55203) {
                    for (int f = k; WordDataSet[i][f] == NULL; f++) {
                        WordDataSet[i][f] = WordDataSet[i][f + 1];
                    }
                }
                else*/ WordDataSet[i][k] = NULL;//문장부호 삭제
            }
        }
        i++;
    }

    for (int j = 0; j < i; j++) { // 저장된 문자열을 출력합니다.
        printf("%s\n", WordDataSet[j]);
    }

    return 0;
}
  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 코드로 물어보세요. nowp 2021.3.15 08:19
  • 문자열 안의 특정 문자를 NULL 로 바꾸는게 가능하다고요?? 빈문자열로 바꾸시면 되지 않을까요?? 엽토군 2021.3.15 11:54
  • " "으로 바꾸면 된다는 말씀이신가요?? 그렇게 바꾼다면 어떤 문자열은 한칸 띄워진 채로 시작하고 어떤 문자열을 잘 출력돼서 출력이 이상하게 돼서요.. 굳이 코드를 안올려도 될 것 같은 문제라서 코드를 안올린겁니다.. 질문 수정해서 코드 올려보겠습니다! 알 수 없는 사용자 2021.3.15 16:06
  • 중간에 주석처리한 곳은 어떻게든 방법을 찾아보려고 문장부호 뒤에 한글이 있다면 그 문장부호를 없애고 한 칸씩 땡겨보면 되지 않을까 싶은 생각으로 작성한 곳입니다.. 실패했고요 알 수 없는 사용자 2021.3.15 16:10
  • null terminated string 개념은 아나요? nowp 2021.3.15 17:52
  • null이 stirng의 마지막을 알려주는 것 말씀하시는건가요? 알 수 없는 사용자 2021.3.15 18:23
  • 제가 말씀드린 건 "" 였어요. 엽토군 2021.3.15 19:17
  • 그렇게 해봤더니 const char* 형식의 값을 char 형식의 엔티티에 할당할 수가 없다고 오류가 떠가지고.. 알 수 없는 사용자 2021.3.15 19:20

2 답변

  • 문자를 없애는 것만 생각한다면, 다음과 같이 할 수 있습니다.

    for 를 while 로 바꾸었고, d 라는 변수를 도입하여, 건너뛸 문자갯수를 기억합니다. d0이 아니라면 k+d 인덱스의 문자를 k 인덱스 자리에 복사해 줍니다.

    
        while (!feof(f)) {
            fscanf(f, "%s", WordDataSet[i]); // 텍스트파일에서 문자열을 받습니다.
            int size = strlen(WordDataSet[i]); //  텍스트파일에 있는 문자열의 길이를 구합니다.
            int d = 0;
            int k = 0;
            while (1) {
                while (WordDataSet[i][k+d] >= 33 && WordDataSet[i][k+d] <= 47) {
                    d++;
                }
                if(d) {
                    WordDataSet[i][k] = WordDataSet[i][k+d];
                }
                if(WordDataSet[i][k+d] == 0) break;
                k++;
            }
            i++;
        }
    

    똑같은 건데 포인터를 이용한 것.

    
        while (!feof(f)) {
            fscanf(f, "%s", WordDataSet[i]); // 텍스트파일에서 문자열을 받습니다.
            int size = strlen(WordDataSet[i]); //  텍스트파일에 있는 문자열의 길이를 구합니다.
            char *s;
            char *d;
    
            for( d=s=WordDataSet[i] ; ; s++, d++) {
                while(*s >= 33 && *s <= 47) {
                    s++;
                }
                *d = *s;
                if(*s == 0) break;
            }
            i++;
        }
    
  • 코드를 좀 수정해 보았습니다!

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    
    #define R 1001
    using namespace std;
    
    char word[R]; // 텍스트파일에서 문자를 받아오는 변수입니다.
    char WordDataSet[R][R]; // 받은 데이터를 담고있는 2차원 배열입니다.
    string str;
    
    int main() {
    
        FILE* fo = fopen("input.txt", "r");
        if (fo == NULL) printf("None file\n");
        char oword[100];//텍스트 파일을 그대로 받아올 변수
        fgets(oword, 100, fo);
        fclose(fo);
        printf("-----------------------원본--------------------------\n\n%s\n", oword);//텍스트 파일 원본 출력
    
        FILE* f = fopen("input.txt", "r"); // 파일을 읽기 형식으로 받아줍니다. 
    
        if (f == NULL) printf("None file\n"); // 파일이 존재하지 않을 경우 예외처리입니다.
        int i = 0; //  받은 데이터들의 인덱스를 표시하는 변수입니다.
    
        while (!feof(f)) {
            fscanf(f, "%s", WordDataSet[i]); // 텍스트파일에서 문자열을 받습니다.
            int size = strlen(WordDataSet[i]); //  텍스트파일에 있는 문자열의 길이를 구합니다.
            for (int k = 0; k < size; k++) {
                if (WordDataSet[i][k] >= 33 && WordDataSet[i][k] <= 47) {
                    str = WordDataSet[i];
                    str.erase(k, 1);
                    (string)WordDataSet[i] = str;
                }
                else if (WordDataSet[i][k] == 63) {
                    str = WordDataSet[i];
                    str.erase(k, 1);
                    (string)WordDataSet[i] = str;
                }
            }
            i++;
        }
        printf("-----------------------------------------------------\n");
        for (int j = 0; j < i; j++) { // 저장된 문자열을 출력합니다.
            printf("%s\n", WordDataSet[j]);
        }
    
        return 0;
    }
    

    그런데 이렇게 바꿔보니 아예 문장부호들이 그대로 나오네요.. 문제가 있나요? 위에서 주석처리했던 부분은 좀만 더 만지다보니 아예 글자가 깨져서 나오길래 이렇게 바꿔보았습니다. string 은 특정 문자를 지우는게 함수로 쉽게 나와있더군요..

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

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

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

(ಠ_ಠ)
(ಠ‿ಠ)