본문 바로가기
c/자습

문자와 문자열(쉽게 풀어쓴 C언어 EXPRESS)

by 지트리아 2023. 1. 4.

용어정리

 

 

 

 

본문정리

문자와 문자열

문자열이란 일련의 문자들의모임이다.

문자열의 은 반드시 NULL 문자로 표시를 해주어야한다. 즉 문자 배열은 저장하고자하는 문자열의 크기보다 항상 하나 더 커야 한다. 

초기화 하는 방식에는 2가지가 있다.

char str[4] = { 'a', 'b', 'c', '\0' } ;//1번 방식
char str[4] = "abc"; //2번 방식

2번 방식은 자동으로 문자열의 끝에 NULL문자를 추가한다.

char str[] = "abc"; //문자의 개수를 셀 필요가 없다

 

문자열 변경시 다음은 불가하다.

char str[10] = "Hello";
str = "world"; // 불가

str은 주소이기 때문이다.

 

문자열 상수는 텍스트 세그먼트라고 불리우는 특수한 메모리 영역에 저장된다.

{모든 변수는 데이터 세그먼트라고 불리는 영역에 저장된다. 여기서 데이터 세그먼트는 값을 변경할 수 있는 메모리 영역이다.

텍스트 세그먼트는 값을 읽기만 하고 변경할 수 없는 메모리 영역이다.}

char *p = "Hello"; // 여기서 포인터 변수 p는 데이터 세그먼트에 할당된다.
strcpy(p,"world"); // 포인터가 텍스트 세그먼트를 가리키고 있는데 이를 "world"로 바꾸려한다면
//텍스트 세그먼트를 바꾸려하는 것이므로 규칙에 위배된다.
p = "world"; // 포인터가 텍스트 세그먼트 중 하나를 가리키기 때문에 가능하다.

 

문자 입출력 라이브러리

int getchar(void) 하나의 문자를 읽어서 반환한다.
void putchar(int c) 변수 c에 저장된 문자를 출력한다.
int _getch(void) 하나의 문자를 읽어서 반환한다.(버퍼 사용 x)
void _putch(int c) 변수 c에 저장된 문자를 출력한다.(버퍼 사용 x)
scanf("%c", &c) 하나의 문자를 읽어서 변수 c에 저장한다.
printf("%c", c) 변수 c에 저장된 문자를 출력한다.

 

getchar()를 보면 char가 아닌 int를 사용한다. 이유는 EOF(보통 -1로 정의)문자를 체크하기 위해서다.

getchar()는 버퍼를 사용하지만 getch()는 버퍼를 사용하지 않는다.

 

_getch와 _putch는 <conio.h>를 포함하여야 한다. 이들은 에코를 사용하지 않는다.

 

문자열 입출력 라이브러리

int scanf("%s", s) 문자열을 읽어서 문자배열 s[]에 저장
int printf("%s", s) 배열 s[]에 저장되어 있는 문자열을 출력한다.
char *gets_s(char *s, int size) 한 줄의 문자열을 읽어서 문자 배열 s[]에 저장한다.
int puts(const char *s) 배열 s[]에 저장되어 있는 한 줄의 문자열을 출력한다.

 

scanf()는 하나의 단어 밖에 입력을 못한다.

만약 여러 단어로 이루어진 한 줄 전체를 입력받으려면 gets_s()를 사용하여햐 한다. gets_s()는 줄바꿈 문자가 나올 때까지 한 줄의 라인을 문자열로 입력받는다.gets_s()는 자동으로 NULL 문자를 추가한다. 

문자열의 끝에 있는 NULL문자는 줄바꿈 문자로 변경된다.

 

문자 처리 라이브러리

이하는 ctype.h 헤더 파일을 포함해야 한다.

isalpha(c) c가 영문자인가?
issupper(c) c가 대문자인가?
islower(c) c가 소문자인가?
isdigit(c) c가 숫자인가?(0~9)
isalnum(c) c가 영문자이나 숫자인가?
isxdigit(c) c가 16진수의 숫자인가?
isspace(c) c가 공백문자인가?
ispunct(c) c가 구두점 문자인가?
isprintf(c) c가 출력가능한 문자인가?
iscntrl(c) c가 제어 문자인가?
isascii(c) c가 아스키 코드인가?

 

toupper(c) c를 대문자로 바꾼다.
tolower(c) c를 소문자로 바꾼다.
toascii(c) c를 아스키 코드로 바꾼다.

 

문자열 처리 라이브러리 함수

이하는 string.h에 선언되어 있다.

strlen(s) 문자열 s의 길이를 구한다.
strcpy(s1, s2) s2를 s1에 복사한다.
strcat(s1, s2) s2를 s1의 끝에 붙여넣는다.
strcmp(s1, s2) s1과 s2를 비교한다.
strncpy(s1,s2,n) s2의 최대 n개의 문자를 s1에 복사한다.
strncat(s1,s2,n) s2의 최대 n개의 문자를 s1의 끝에 붙여넣는다.
strncmp(s1, s2, n) 최대 n개의 문자까지 s1과 s2를 비교한다.
strchr(s, c) 문자열 s안에서 문자 c를 찾는다.
strstr(s1, s2) 문자열 s1에서 문자열 s2를 찾는다.
char *strtok( s, delimit) 문자열 s를 delimit를 이용하여 토큰으로 분리한다.

 

문자열 수치 변환

sscanf와 sprintf는 string이 붙은 것으로 키보드에서 입력받는 대신에 문자열에서 입력을 받으며, 모니터로 출력하는 대신에 문자열로 출력한다.

int atoi(const char *str) str을 int형으로 변환한다.
double atof(const char *str) str을 double형으로 변환한다. 

 

문자열 여러 개를 저장하는 방법

2차원 문자 배열을 사용하는 방법과 문자 포인터 배열을 사용하는 방법으로 2가지가 있다. 앞에 방식은 공간이 낭비될 수 있는 반면 후자는 문자열의 내용을 변경할 수 없다는 것이다.

 

 

본문제

Q1. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
    char c;

    printf("문자를 입력하시오: ");
    scanf("%c", &c);

    printf("아스키 코드값=%d", (int)c);


    return 0;
}

 

Q2. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char c[150];
    char  sep[] = " \t\n";
    char* token = NULL;

    printf("공백 문자가 있는 문자열을 입력하시오: ");
    gets_s(c, 150);

    token = strtok(c, sep);
    while (token != NULL) {
        printf("%s", token);
        token = strtok(NULL, sep);
    }

    return 0;
}

 

Q3. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int str_chr(char* s, int c) {
    int result = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] == c) {
            result++;
        }
    }
    return result;
}

int main(void) {
    char c[150], fc = 0;

    printf("문자열을 입력하세오: ");
    gets_s(c, 150);
    printf("개수를 셀 문자를 입력하시오: ");
    scanf("%c", &fc);

    printf("%c의 개수: %d", fc, str_chr(c, (int)fc) )

    return 0;
}

 

Q4. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

void str_chr(char* str) {
    int result = 0;
    for (char c = 'a'; c <= 'z'; c++) {
        for (int i = 0; str[i] != '\0'; i++) {
            if (str[i] == c) {
                result++;
            }
        }
        printf("%c: %d\n", c, result);
        result = 0;
    }
}

int main(void) {
    char str[200];

    printf("문자열을 입력하시오: ");
    gets_s(str, 200);

    str_chr(str);

    return 0;
}

 

Q5.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    int c = 0;

    while (1) {
        printf("문자를 입력하시오: ");
        if ((c = getchar()) != (int)'.') {
            if (c >= (int)'a' && c <= (int)'z') {
                c = toupper(c);
            }
            else if (c >= (int)'A' && c <= (int)'Z') {
                c = tolower(c);
            }
            putchar((char)c); getchar();
            printf("\n");
        }
        else {
            break;
        }
    }

    return 0;
}

 

Q6.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

void str_upper(char* s) {
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] >= 'a' && s[i] <= 'z') {
            s[i] = toupper(s[i]);
        }
    }
}

int main(void) {
    char str[150];

    printf("문자열을 입력하시오: ");
    gets_s(str, 150);

    str_upper(str);
    printf("변환된 문자열: ");
    for (int i = 0; str[i] != '\0'; i++) {
        printf("%c", str[i]);
    }

    return 0;
}

 

Q7.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int get_response(char* prompt) {
    for (int i = 0; prompt[i] != '\0'; i++) {
        if (prompt[i] >= 'A' && prompt[i] <= 'Z') {
            prompt[i] = tolower(prompt[i]);
        }
    }
    if (!(strcmp(prompt, "yes")) || !(strcmp(prompt, "ok"))) {
        return 1;
    }
    else if (!(strcmp(prompt, "no"))) {
        return 0;
    }
}

int main(void) {
    char str[150];

    printf("게임을 하시겠습니까: ");
    scanf("%s", str);
    if (get_response(str)) {
        printf("긍정적인 답변");
    }
    else {
        printf("부정적인 답변");
    }

    return 0;
}

 

Q8.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[150];
    char sep[] = " ";
    char* token;
    int result = 0;

    printf("문자열을 입력하시오: ");
    gets_s(str, 150);

    token = strtok(str, sep);
    
    while (token != NULL) {
        result++;
        token = strtok(NULL, sep);
    }

    printf("단어의 수는 %d입니다.", result);

    return 0;
}

 

Q9.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[150];

    printf("텍스트를 입력하시오: ");
    gets_s(str, 150);

    if (str[0] >= 'a' && str[0] <= 'z') {
        str[0] = toupper(str[0]);
    }
    if (str[strlen(str) - 1] != '0') {
        strcat(str, ".");
    }

    printf("%s", str);

    return 0;
}

 

Q10.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[150];
    int start = 0, last = 0, result = 1;
    printf("문자열을 입력하시오: ");
    gets_s(str, 150);

    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] >= 'A' && str[i] <= 'Z') {
            if (str[i] == ' ') {
                continue;
            }
            str[i] = tolower(str[i]);
        }
    }

    last = strlen(str) - 1;

    while (1) {
        if (start > last) {
            break;
        }
        if (str[start] != str[last]) {
            result = 0;
            break;
        }
        start++, last--;
    }

    if (result) {
        printf("회문입니다.");
    }
    else {
        printf("회문이 아닙니다.");
    }

    return 0;
}

 

Q11.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str1[150], *str2[100];
    char sep[] = " ";
    char* token = NULL;
    int i = 0;

    printf("문자열을 입력하시오: ");
    gets_s(str1, 150);

    token = strtok(str1, sep);

    while (token != NULL) {
        str2[i] = token;
        token = strtok(NULL, sep);
        i++;
    }

    for (int j = i - 1; j >= 0; j--) {
        printf("%s ", str2[j]);
    }

    return 0;
}

 

Q12.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char name[100], * chagename[100];
    char sep[] = " ";
    char* token = NULL;
    int k = 0;

    printf("성과 이름을 대문자로 입력하시오: ");
    gets_s(name, 100);

    for (int i = 0; name[i] != '\0'; i++) {
        if (name[i] >= 'A' && name[i] <= 'Z') {
            name[i] = tolower(name[i]);
        }
    }

    token = strtok(name, sep);
    while (token != NULL) {
        chagename[k] = token;
        token = strtok(NULL, sep);
        k++;
    }

    for (int i = k - 1; i >= 0; i--) {
        printf("%s", chagename[i]);
        if (i == 1) {
            printf(", ");
        }
    }

    return 0;
}

 

Q13.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[200];
    int count = 0;

    printf("문자열을 입력하시오: ");
    gets_s(str, 200);

    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == '.' || str[i] == ',') {
            count++;
        }
    }
    printf("구두점의 개수는 %d입니다.", count);
    return 0;
}

 

Q14.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[200], find[150], change[150], * result[200] = { 0 };
    char* token;
    char sep[] = " ";
    int i = 0;

    printf("문자열을 입력하시오: ");
    gets_s(str, 200);
    printf("찾을 문자열: ");
    gets_s(find, 150);
    printf("바꿀 문자열: ");
    gets_s(change, 150);

    token = strtok(str, sep);

    while (token != '\0') {
        if (!strcmp(token, find)) {
            strcpy(token, change);
        }
        result[i] = token;
        token = strtok(NULL, sep);
        i++;
    }

    printf("수정된 문자열: ");
    for (int j = 0; result[j] != 0; j++) {
        printf("%s ", result[j]);
    }

    return 0;
}

 

Q15.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char s[100];
    int a, b;

    printf("연산을 입력하시오: ");
    scanf(" %s %d %d", s, &a, & b);

    if (!strcmp(s, "add")) {
        printf("연산의 결과: %d", a + b);
    }
    else if (!strcmp(s, "sub") ) { 
        printf("연산의 결과: %d", a - b);
    }
    else if (!strcmp(s, "mul") ) {
        printf("연산의 결과: %d", a * b);
    }
    else if (!strcmp(s, "div")) {
        printf("연산의 결과: %d", a / b);
    }

    return 0;
}

 

Q16.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {
    char s[200];
    int i = 0, j = 0, count = 0, len = 0;

    printf("광고하고싶은 텍스트를 입력하시오: ");
    gets_s(s, 200);
    printf("--------------------------------------------------------------\n");
    len = strlen(s);
    while (1) {
        for (i; i < len; i++) {
            printf("%c", s[i]);
        }
        for (j = 0; j < count; j++) {
            printf("%c", s[j]);
        }
        
        printf("\n");
        count++;
        if (count == len) {
            count = 0;
        }
        i = count;
    }
    return 0;
}

댓글