[C언어] 문자와 문자열 관련 함수

김민정·2024년 9월 4일
0
post-thumbnail

Part 04. C언어의 깊은 이해

벌써 Part4이다!👏🏻👏🏻👏🏻👏🏻👏🏻
기본적인 것은 모두 배웠고 심화 과정이라 생각해도 좋다.
진지하게 배우기보단 즐기는 것을 추천한다~!

Chapter 21. 문자와 문자열 관련 함수

이번 Chapter에서는 몇 개의 함수가 아니라 데이터의 이동경로를 의미하는 '스트림'과 이를 기반으로 하는 '데이터 입출력'에 대한 개념적 이해다.

21-1 "스트림과 데이터의 이동"

데이터의 입력과 출력은 프로그램의 흐름을 뜻하는 것이다.
대표적인 입력 장치는 마우스, 키보드, 화상 카메라 등이 있고 대표적인 풀력 장치로는 모니터, 프린터 등이 있다. 파일은 입출력 장치가 될 수 있다.

입출력 장치는 매우 포괄적이며 데이터를 컴퓨터 내부로 받아들이는 것이 입력이고 외부로 전송하는 것이 출력이다.

데이터의 이동수단이 되는 스트림

프로그램상에서 모니터와 키보드를 대상으로 데이터를 입출력 하기 위해서는 이들을 연결시켜 주는 다리가 필요한데 이러한 다리 역할을 하는 매개체를 가리켜 스트림(stream)이라 한다.
스트림은 운영체제(OS)에서 제공하는 소프트웨어적인(소프트웨어로 구현되어 있는) 가상의 다리이다. 운영체제는 외부장치와 프로그램과의 데이터 송수신의 도구가 되는 스트림을 제공하고 있다.

스트림의 생성과 소멸

콘솔(일반적으로 키보드 & 모니터) 입출력과 파일 입출력 사이에는 차이점이 하나 있다.
파일과의 연결을 위한 스트림의 생성은 우리가 직접 요구해야하지만, 콘솔과의 연결을 위한 스트림의 생성은 요구할 필요가 없다는 것이다.
콘솔 입출력을 위한 '입력 스트림'과 '출력 스트림'은 프로그램이 실행되면 자동으로 생성되고, 프로그램이 종료되면 자동으로 소멸되는 스트림이다.
이 둘을 기본적으로 제공하는 것이 표준 스트림 (standard stream)이고 표준 스트림에는 '에러 스트림'도 존재한다. 이 각각을 stdin, stdout, stderr라고 부른다.

  • stdin : 표준 입력 스트림 (키보드 대상으로 입력)
  • stdout : 표준 출력 스트림 (모니터 대상으로 출력)
  • stderr : 표준 에러 스트림 (모니터 대상으로 출력)

stdoutstderr을 구분하는 것은 이후에 '입출력 리다이렉션(redirection)'이라는 기술을 익히고 나면 표준 에러 스트림의 출력 대상(데이터 전송의 방향)을 변경시킬 수 있어 알 수 있게 된다.
이것 이외의 스트림들은 프로그래머가 직접 형성해야 한다.
예를 들어 파일 입출력을 위한 스트림은 직접 형성해야 한다.

스트림이라 불리는 이유는 데이터의 이동을 한 방향으로만 형성하기 때문이다.


21-2 "문자 단위 입출력 함수"

문자 출력 함수: putchar, fputc

모니터로 하나의 문자를 출력할 때 일반적으로 사용하는 두 함수는 다음과 같다.

putchar함수는 인자로 전달된 문자정보를 stdout으로 표현되는 표준 출력 스트림으로 전송하는 함수이다.
따라서 인자로 전달된 문자를 모니터로 출력하는 함수라 할 수 있다.
fputc함수는 문자를 전송할 스트림을 지정할 수 있다.
즉, fputc함수를 이용하면 stdout뿐만 아니라, 파일을 대상으로도 데이터를 전송할 수 있다. fputc함수의 두 번째 인자를 통해서 출력의 대상을 지정한다. 따라서 이 인자에 표준 출력 스트림을 의미하는 stdout을 전달하면 putchar함수와 동일한 함수가 된다.

문자 입력 함수: getchar, fgetc

키보드로부터 하나의 문자를 입력 받을 때 일반적으로 사용하는 두 함수는 다음과 같다.

getchar함수는 stdin으로 부터 표현되는 표준 입력 스트림으로부터 하나의 문자를 입력 받아서 반환하는 함수이다.
따라서 키보드로부터 하나의 문자를 입력 받는 함수라 할 수 있다.
fgetc함수는 putchar, fputc함수의 관계와 동일하게 문자를 입력 받을 대상정보를 인자로 전달한다.

예제를 통해 4개의 함수를 살펴보자.

#include <stdio.h>

int main()
{
    int ch1, ch2;

    ch1=getchar();  // 문자 입력
    ch2=fgetc(stdin); // 엔터 키 입력

    putchar(ch1);   // 문자 출력
    fputc(ch2, stdout); // 엔터 키 출력
    return 0;
}

> 출력
m
m

이 예제에서 문자를 입력하는데 왜 int형 변수에 문자를 저장하는 것일까?
getchar 함수와 fgetc함수의 반환형이 int이기 때문에 그렇다. 이것이 무슨 상관일까? EOF를 배움으로써 알아보자.

문자 입출력에서의 EOF

EOF는 End Of File의 약자로 파일의 끝을 표현하기 위해서 정의해 놓은 상수이다.
따라서 파일을 대상으로 fgetc 함수가 호출되면, 그리고 그 결과로 EOF가 반환되면 이는 '파일의 끝에 도달해서 더이상 읽을 내용이 없다.'는 뜻이 된다.
fgetc 함수와 getchar 함수가 EOF를 반환하는 건 두 가지 경우에서다.

  1. 함수 호출의 실패
  2. Windows에서 CTRL+Z 키, Linux에서 CTRL+D키가 입력되는 경우

예제를 통해 키보드를 통한 EOF 입력을 확인해보자.

#include <stdio.h>

int main()
{
    int ch;

    while(1)
    {
        ch=getchar();
        if(ch==EOF)
            break;
        putchar(ch);
    }
    return 0;
}

> 출력
Hi!
Hi!
I like C lang
I like C lang
^Z

getchar 함수가 호출된다고 해서 한글자의 문자만 작성할 필요는 없다.
문장이 입력되면 문장을 구성하는 문자의 수만큼 getchar 함수가 호출되면서 모든 문자를 읽어들이기 때문이다.

반환형이 int이고, int형 변수에 문자를 담는 이유

그래서 EOF도 알았는데 왜 int형에 문자를 담을까?
getchar 함수와 fgetc 함수를 관찰하면

int getchar(void);
int fgetc(FILE * stream);

반환되는 것은 1바이트 크기의 문자인데 반환형이 int이다.
Chapter 05에서 "char를 unsigned char로 처리하는 컴파일러도 존재한다."라는 얘기를 한 적이 있다.
두 함수가 반환하는 값 중 하나인 EOF는 -1로 정의된 상수이다.
따라서 반환형이 char형이고 char를 unsinged char로 처리하는 컴파일에 의해서 컴파일이 되었다면 EOF는 반환의 과정에서 엉뚱한 양의 정수로 형 변환이 되어버린다.
따라서 모든 컴파일러가 int는 signed int로 처리하고 어떠한 상황에서도 -1을 인식할 수 있는 int형으로 반환형을 정의해 놓은 것이다. 그리고 반환되는 값을 그대로 유지하기 위해서 int형 변수에 값을 저장하는 것이다.

※ 위 입출력 함수들은 printf 함수나 scanf 함수보다 메모리 공간도 적고 연산해야할 양도 적어 상대적으로 속도가 빠르다.


21-3 "문자열 단위 입출력 함수"

이번에 소개하는 문자열 입력 함수는 scanf 함수와 달리 공백을 포함하는 문자열의 입력을 받을 수 있다.

문자열 출력 함수: puts, fputs

모니터로 하나의 문자열을 출력할 때 일반적으로 사용하는 두 함수는 다음과 같다.

puts함수는 출력의 대상이 stdout으로 결정되어 있지만, fputs함수는 두 번째 인자를 통해서 출력의 대상을 결정할 수 있다.
둘 다 첫번째 인자로 전달되는 주소 값의 문자열을 출력하지만 출력의 형태에 있어 한가지 차이점이 있다.

#include <stdio.h>

int main()
{
    char * str = "Simple String";

    printf("1. puts test ------ \n");
    puts(str);
    puts("So Simple String");

    printf("2. fputs test ------ \n");
    fputs(str, stdout);
    printf("\n");
    fputs("So Simple String", stdout);
    printf("\n");

    printf("3. end of main ------ \n");
    return 0;
}

> 출력
1. puts test ------ 
Simple String
So Simple String
2. fputs test ------
Simple String
So Simple String
3. end of main ------

puts 함수는 문자열 출력 이후 자동으로 개행이 이루어지지만,
fputs 함수는 자동으로 개행이 이루어지지 않는다.

문자열 입력 함수: gets, fgets

두 개의 문자열 입력 함수는 다음과 같다.

gets함수는 다음의 유형으로 호출한다.

int main()
{
	char str[7];	// 7바이트의 메모리 공간 할당
    gets(str);		// 입력 받은 문자열을 배열 str에 저장
    ....
}

gets 함수는 할당 받지 않은 메모리 공간을 침범하여 실행 중 오류가 발생하는 단점이 있다.

fgets함수는 다음과 같다.

int main()
{
	char str[7];
    fgets(str, sizeof(str), stdin);	// stdin으로부터 문자열 입력 받아서 str에 저장
    ....
}

fgets 함수의 의미는 "stdin으로부터 문자열을 입력 받아서 배열 str에 저장하되, sizeof(str)의 길이만큼만 저장해라"라는 뜻이다.
문자열의 저장이기 때문에 마지막 '널 문자'를 위한 공간을 제외하고 채워지게 된다.
예제를 살펴보자.

#include <stdio.h>

int main()
{
    char str[7];
    int i;

    for(i=0;i<3;i++)
    {
        fgets(str, sizeof(str), stdin);
        printf("Read %d: %s \n", i+1, str);
    }
    return 0;
}

> 출력
12345678901234567890
Read 1: 123456
Read 2: 789012
Read 3: 345678

문자열의 길이가 배열의 길이가 넘어서다 보니 잘라서 읽어들이고 있고 널 문자를 포함하여 6개씩만 불러들이는 것을 알 수 있다.

문자열의 길이를 5로 제한해서 다음 예제와 같이 출력되도록 해보자.

#include <stdio.h>

int main()
{
    char Str[5];
    int i;
    for(i=0;i<3;i++)
    {
        fgets(Str, sizeof(Str), stdin);
        printf("Read %d: %s \n", i+1, Str);
    }
    return 0;
}

> 출력
We
Read 1: We

like
Read 2: like

You
Read 3: You

fgets함수는 \n을 만날 때까지 문자열을 읽어 들이는데 \n을 제외시키거나 버리지 않고 문자열의 일부로 받아들인다. 따라서 엔터 키의 정보까지도 문자열 일부로 저장되어 또 한번 개행이 이루어진다.
이번에는 공백을 포함한 문자열 출력이다.

#include <stdio.h>

int main()
{
    char str1[7];
    int i;
    for(i=0;i<3;i++)
    {
        fgets(str1, sizeof(str1), stdin);
        printf("Read %d: %s \n", i+1, str1);
    }
    return 0;
}

> 출력
Y & I
Read 1: Y & I

ha ha
Read 2: ha ha

^^ --
Read 3: ^^ --

중간에 삽입된 공백도 문자열의 일부로 읽어 들인다.


21-4 "표준 입출력과 버퍼"

표준 입출력 기반의 버퍼

지금까지 배운 입출력 함수들을 가리켜 표준 입출력 함수라 한다. ANSC C의 표준에서 정의된 함수이기 때문이다.
(printf, scanf, fputc, fgetc 모두)

이러한 표준 입출력 함수를 통해서 데이터를 입출력 하는 경우, 해당 데이터들은 운영체제가 제공하는 '메모리 버퍼'를 중간에 통과하게 된다. 여기서 말하는 '메모리 버퍼'는 데이터를 임시로 모아두는 (저장하는) 메모리 공간이다. 버퍼가 존재하는 위치는 다음 그림과 같다.

키보드를 통해 입력되는 데이터는 일단 입력버퍼에 저장된 다음에 (버퍼링이 된 다음에) 프로그램에서 읽혀진다.
fgets 함수가 읽어 들이는 문자열은 입력버퍼에 저장된 문자열이다. 엔터키가 눌려지면 키보드로부터 입력된 데이터가 입력 스트림을 거쳐서 입력버퍼로 들어가게 된다.

버퍼링을 하는 이유

데이터를 목적지로 바로 전송하지 않고 중간에 출력버퍼와 입력버퍼를 둬서 전송하고자 하는 데이터를 임시 저장하는 이유는 '데이터 전송의 효율성'과 관련이 있다.
키보드나 모니터와 같은 외부 장치와의 데이터 입출력은 생각보다 시간이 걸리는 작업이다.
버퍼링 없이 키보드가 눌릴 때마다 눌린 문자의 정보를 목적지로 바로 이동시키는 것보다 중간에 메모리 버퍼를 둬서 데이터를 한데 묶어서 이동시키는 것이 보다 효율적이고 빠르다.

출력버퍼를 비우는 fflush함수

출력버퍼가 비워진다는 것은 "출력버퍼에 저장된 데이터가 버퍼를 떠나서 목적지로 이동됨"을 뜻한다.
출력버퍼가 비워지는 시점은 시스템에 따라 그리고 버퍼의 성격에 따라 달라진다.
따라서 출력버퍼가 비워지는 시점이 동일하지 않기 때문에 다음 함수를 알아두면 좋다.

fflush함수는 인자로 전달된 스트림의 버퍼를 비우는 기능을 제공한다.

fflush(stdout);	// 표준 출력 버퍼를 비워라!

어떤 시스템의 어떤 표준 출력버퍼라 할지라도 버퍼에 저장된 내용이 비워지면 데이터가 목적지로 이동한다.
fflush 함수는 파일을 대상으로도 호출이 가능하다. 인자로 파일의 스트림정보가 전달되면, 해당 버퍼에 저장되어 있던 데이터들이 버퍼를 떠나서 파일에 기록된다.
(사실 Window나 Linux와 같은 범용 OS를 사용하고 있다면 stdout을 대상으로 fflush 함수를 호출할 일은 많지 않다.)

입력버퍼 비우기

입력버퍼가 비워진다는 것은 "데이터의 소멸"을 의미한다.
입력버퍼에 남아있는 불필요한 데이터의 소멸을 위해 입력 버퍼를 비워야 하는 경우가 종종 있다.

fflush(stdin);

fflush 함수에 stdin을 인자로 호출하면 입력버퍼를 비워줄거 같다. 하지만 C언어의 표준에서는 위의 결과에 대해 정의하고 있지 않다. (예측이 불가능하다.)
그럼 입력버퍼에 저장된 불필요한 데이터는 어떻게 소멸해야 할까? 예제를 통해 알아보자.

#include <stdio.h>

int main()
{
    char perID[7];
    char name[10];

    fputs("주민번호 앞 6자리 입력: ", stdout);
    fgets(perID, sizeof(perID),stdin);

    fputs("이름 입력: ", stdout);
    fgets(name, sizeof(name), stdin);

    printf("주민번호: %s \n", perID);
    printf("이름: %s \n", name);
    
    return 0;
}

> 출력
주민번호 앞 6자리 입력: 240904
이름 입력: 주민번호: 240904
이름:

6자리를 입력하고 엔터를 치니 이름을 입력하지 못한채 프로그램이 종료되었다.
주민번호를 입력할 때 240904\n 라는 엔터키까지 포함하여 총 7문자가 입력되었다. 널 문자 자리를 제외한 6자리를 fgets 함수의 인자로 전달되었고 남은 \n은 입력버퍼에 남아있게 된다. 그리고 이어서 fgets 함수가 호출될 때 버퍼에 남아있는 \n을 읽어버려 종료되는 것이다.
그렇다면 남아있는 \n을 읽어들이지 않기 위해 입력버퍼에 남아있는 데이터를 지우려면 어떻게 하면 좋을까?

void ClearLineFromReadBuffer(void)
{
	while(getchar()!='\n');
}

이 함수를 정의하고 적절할 때 호출하면 입력버퍼에 저장된 문자들을 읽어 들이면 지워진다.

#include <stdio.h>

void ClearLineFromReadBuffer(void)
{
	while(getchar()!='\n');
}

int main()
{
    char perID[7];
    char name[10];

    fputs("주민번호 앞 6자리 입력: ", stdout);
    fgets(perID, sizeof(perID),stdin);
    ClearLineFromReadBuffer();  // 입력버퍼 비우기

    fputs("이름 입력: ", stdout);
    fgets(name, sizeof(name), stdin);

    printf("주민번호: %s \n", perID);
    printf("이름: %s \n", name);
    
    return 0;
}

> 출력
주민번호 앞 6자리 입력: 240904
이름 입력: Min
주민번호: 240904
이름: Min

주민번호 앞 6자리 입력: 240904-4321567
이름 입력: MJ
주민번호: 240904
이름: MJ

주민번호를 초과해서 작성해도 입력버퍼에 남아있는 데이터가 비워져 정상적으로 출력되는 것을 확인할 수 있다.


21-5 "입출력 이외의 문자열 관련 함수"

표준 C에서는 문자열과 관련된 다양한 함수들을 정의하고 있다.
헤더파일 string.h에 선언된 문자열 관련 함수들 중 사용 빈도수가 높은 몇몇 함수들을 알아보자.

문자열의 길이를 반환하는 함수: strlen

우리가 여태까지 sizeof(str)/sizeof(int)식으로 사용한 문자열의 길이를 반환하는 함수이다.

strlen함수의 반환형 size_t는 일반적으로 다음과 같이 선언된다.

typedef unsigned int size_t;

위가 의미하는 바는 "unsigned int의 선언을 size_t로 대신할 수 있다."이다.
즉, 위의 typeof 선언으로 인해 size_t가 unsigned int를 대신할 수 있게 된 것이다.
따라서 size_t len = unsigned int len 동일한 선언이다.

strlen함수의 호출방법은 다음과 같다.

int main()
{
	char str[]="1234567";
    printf("%u \n", strlen(str));	// 문자열 길이인 7 출력
    ....
}

사실상 strlen 함수의 반환형은 size_t (unsigned int)이므로 strlen 함수의 반환 값을 int형 변수에 저장하고 서식문자 %d로 출력하는 것이 더 흔한 일이다.

이제 예제를 봐보자. 이번 예제에서는 fget 함수호출을 총해서 문자열을 입력 받고 싶은데 \n문자는 문자열에서 제외하고 받을 수 있는 방안을 제시해준다.

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

void RemoveBSN(char str[])
{
    int len = strlen(str);
    str[len-1] = 0;
}
int main()
{
    char str[100];
    printf("문자열 입력: ");
    fgets(str, sizeof(str), stdin);
    printf("길이: %d, 내용: %s \n", strlen(str), str);

    RemoveBSN(str);
    printf("[BSN 제거 후] 길이: %d, 내용: %s \n", strlen(str), str);
    return 0;
}

> 출력
문자열 입력: Good Night~
길이: 12, 내용: Good Night~

[BSN 제거 후] 길이: 11, 내용: Good Night~

첫 fgets함수 실행 이후엔 개행이 두번 이루어졌는데 이는 남아있는 \n이 있기 때문이다.

문자열을 복사하는 함수들: strcpy, strncpy

문자열 복사에 사용되는 함수는 아래 두가지가 있다.

strcpy함수를 호출하는 형태는 아래와 같다.

int main()
{
	char str1[30] = "Simple String";
    char str2[30];
    strcpy(str2, str1);	// str1 문자열을 str2에 복사
    ....
}

문자열이 복사될 때 복사될 배열의 길이가 문자열의 길이보다 작지 않도록 유의해야한다.

strncpy함수의 호출 형태는 아래와 같다.

int main()
{
	char str1[30] = "Simple String";
    char str2[30];
    strncpy(str2, str1, sizeof(str2));
    ....
}

str에 저장된 문자열을 str2에 복사하되 최대 sizeof(str2)의 반환 값 크기만큼 복사한다.

예제를 통해 두 함수를 더 이해해보자.

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

int main()
{
    char str1[20] = "1234567890";
    char str2[20];
    char str3[5];

    // Case 1
    strcpy(str2, str1);
    puts(str2);

    // Case 2
    strncpy(str3, str1, sizeof(str3));
    puts(str3);

    //Case 3
    strncpy(str3, str1, sizeof(str3)-1);
    str3[sizeof(str3)-1] = 0;
    puts(str3);

    return 0;
}

> 출력
1234567890
123451234567890
1234

strncpy(str3, str1, sizeof(str3)); 문장을 보면 sizeof(str3)의 크기가 5이니 5개의 문자만 복사될 줄 알았는데 이 5개의 문자 안에 널 문자가 포함되지 않는다는 문제가 있기 때문에 출력 두번째 줄과 같이 출력이 된다.
따라서 strncpy함수의 세번째 인자로 배열의 실제 길이보다 하나 작은 값을 전달해서 널 문자가 삽입될 공간을 남겨두고 복사를 진행해야 한다. 그리고 이어서 배열의 끝에 널 문자를 삽입해야 한다.

문자열을 덧붙이는 함수들: strcat, strncat

문자열의 뒤에 다른 문자열을 복사하는 기능을 가진 함수는 아래 두 가지가 있다.

strcat함수의 호출 형태는 다음과 같다.

int main()
{
	char str1[30] = "First~";
    char str2[30] = "Second";
    strcat(str1, str2);	//  str1 문자열 뒤에 str2를 복사
    ....
}

strcat함수가 호출되면 str2의 문자열이 str1 문자열 뒤에 덧붙여지는데 덧붙여지는 형태는 다음과 같고 이때, 널 문자가 어떻게 처리되는지 유의해서 보자.

덧붙임이 시작되는 위치는 널 문자 다음이 아닌, 널 문자가 저장된 위치에서부터이다.

strncat함수의 호출문은 다음과 같다.

strncat(str1, str2, 8);

이 문장이 의미하는 바는 "str2의 문자열 중 최대 8개를 str1의 뒤에 덧붙인다."이다.
즉, str2의 길이가 8을 넘어선다면 8개의 문자까지만 str1에 덧붙인다는 것이다. 이 8개의 문자에는 널 문자가 포함되지 않는다! 따라서 실제로는 널 문자를 포함한 9개의 문자가 str1의 널 문자 자리에 붙여지게 된다.
따라서 문장 전체를 붙여주는 strcat함수와 달리 strncat함수는 마지막에 널 문자를 자동으로 삽입해준다.
예제를 살펴보자.

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

int main()
{
    char str1[20] = "First~";
    char str2[20] = "Second";

    char str3[20] = "Simple Num: ";
    char str4[20] = "1234567890";

    // Case 1
    strcat(str1, str2);
    puts(str1);

    // Case 2
    strncat(str3, str4, 7);
    puts(str3);

    return 0;
}

> 출력
First~Second
Simple Num: 1234567

문자열을 비교하는 함수들: strcmp, strncmp

보통 동등비교 연산자(==)를 통해 주소 값이 같은지 비교할 순 있어도 문자열의 내용이 같은지 비교할 수 없다.
문자열의 내용이 같고 다름을 비교하는 기능을 가진 함수는 아래 두 가지이다.

두 함수 모두 인자로 전달된 두 문자열의 내용을 비교하여 다음의 결과를 반환한다.
단, strncmp함수는 세 번째 인자로 전달된 수의 크기만큼만 문자를 비교한다. 즉, 앞에서부터 시작해서 중간부분까지 부분적으로만 비교할 수 있다.

  • s1이 더 크면 0보다 큰 값 반환
  • s2가 더 크면 0보다 작은 값 반환
  • s1과 s2의 내용이 모두 같다면 0 반환

여기서 크다 작다의 대소비교 기준은 아스키 코드 값을 기준으로 결정된다.

예를 들어 ABCDABCC의 문자열이 같은지 비교할 때
D의 아스키 코드 값이 C보다 크기 때문에 실행 결과로 양수가 출력된다.
이때 반환되는 양수의 값은 구체적으로 정해져 있지 않아 양수인지 음수인지만 파악하면 된다.

음수가 반환되는 경우는 ABCDABCDE의 문자열을 비교할 때 첫 번째 문자열의 마지막은 널 문자(0)이고 두번째 문자열은 E이므로 두 번째 문자열이 더 크기 때문에 음수를 반환한다.

따라서, 0이 반환되면 동일한 문자열, 0이 반환되지 않는다면 동일하지 않은 문자열인 것만 알면 된다.
예제를 살펴보자.

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

int main()
{
    char str1[20];
    char str2[20];
    printf("문자열 입력 1: ");
    scanf("%s", str1);
    printf("문자열 입력 2: ");
    scanf("%s", str2);

    if(!strcmp(str1, str2))
        puts("두 문자열은 완전히 동일합니다.");
    else
    {
        puts("두 문자열은 동일하지 않습니다.");
        if(!strncmp(str1, str2, 3))
            puts("그러나 앞 세 글자는 동일합니다.");
    }
    return 0;
}

> 출력
자열 입력 1: Simple
문자열 입력 2: Simon
두 문자열은 동일하지 않습니다.
그러나 앞 세 글자는 동일합니다.

그 외 변환 함수들

추가로 알아두면 도움이 되는 함수를 소개하려 한다.
헤더파일 <stdlib.h>에 선언된 함수들이다.

// 문자열의 내용을 int형으로 변환
int atoi(const char * str);

// 문자열의 내용을 long형으로 변환
long atol(const char * str);

// 문자열의 내용을 double형으로 변환
double atof(const char *str);

문자열로 표현된 정수나 실수의 값을 해당 정수나 실수의 데이터로 변환해야 하는 경우가 간혹 있다.
예를 들어 문자열 "123"을 정수 123으로 변환해야하 하거나,
문자열 "3.14"를 실수 3.14로 변환해야하는 상황이다.
위의 함수들을 사용하면 편하게 변환할 수 있다.
예제를 살펴보자.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char str[20];
    printf("정수 입력: ");
    scanf("%s", str);
    printf("%d \n", atoi(str));

    printf("실수 입력: ");
    scanf("%s", str);
    printf("%g \n", atof(str));

    return 0;
}

> 출력
정수 입력: 15 
15
실수 입력: 12.456
12.456

<Review>

Part 04에 들어오게 되다니...!!!
작년 12월부터 코딩을 시작하고 C언어 책을 완독하겠다고 마음 먹었지만 이것저것에 치이다보니 거의 10개월째에 도달하게 되었다...😂

스터디에서 정해놓은 진도만큼 해내다보니 올 수 있었던거 같다.
확실히 반강제성을 띄어야 하는,,,ㅎㅎㅎ 의식으로 무의식을 조정하자!!!
아자아자 화이팅~!

profile
백엔드 코린이😁

0개의 댓글

관련 채용 정보