카테고리 없음

c언어정리7

dywm23 2025. 3. 19. 21:17
  • 문자열

문자열의 메모리 할당

이전에 chr 변수를 만들 때  'a' 같이 한단어만을 저장한 변수를 생성하였다. (미리 문자열을 선언하는 방식을 배우긴함.)

2강 // string(문자열) 미리보기 = char + char + char... =char[] 미리보기
char name [30]; // name에 30바이트의 공간을 미리 만들어둠. 문자는 1바이트씩 사용을 한다.
 

하지만 문자열을 사용하면 여러 글자를 한번에 저장 할 수 있다.

//문자나 문자를 합쳐서 문자열이라고 한다.
// 문자열은 끝 부분에 null문자(\0)를 붙여서 경계를 표시해줘야 하는데 이것은 문자마다 저장되는 바이트수가 각기 다르기 떄문이다.
// 이것 없으면 에러 발생하거나 문제가 생긴다.
//영어는 글자마자 1바이트지만 한글 같은 경우 2바이트로 저장될수도있고 3바이트로 저장될 수도 있다.
//문자 리터럴: 배열의 선언없이 한번에 작성된 문자열로 한번에 만들어 일회용으로 사용하는 경우에 쓰임. 최대 약 2048바이트까지 가능.
//즉 한글은 1024바이트 또는 700이 넘어가지 않는 바이트까지 저장이 가능하다.
//문자열(문자의 배열): 배열 선언 후 저장한 문자열로 char str[]= "heelo world";
//문자열 리터럴이 배열에 복사되고 따옴표가 붙은 개별 문자열은 동일하게 2048 바이트 이하
// 문자열을 연결하면 최대 655545 바이트까지 리터럴을 생성 가능
#include <stdio.h>

int main(){

    char str1[6]; // 5글자 +null문자(\0)
    char str2[6]="Hello"; //저장이 되기는 하지만 hellow로 저장하면 끝 문자가 표시가 안되있는 문자로 위험한 문자열이 만들어짐
    char str3[6]= {'h','e','l','l','o','\0'};
    printf("%s\n", str2);
    printf("%s\n",str3);

    //문자열 == 배열 사용방법, 문자열 포인터 == 배열 포인터 사용방법
    char str4[] = "world";
    char * ptr_str4= str4; //&str4[0]으로 해도되는데 int와 달리 문자열은 그냥 배열로 작성하는 경우가 많음.
    printf("%s\n", str4);

    str4[2] = 'a';   //문자를 ' '로 감싸줘야한다. ""로 감싸는건 string
    *(ptr_str4 +1)='e';
    printf("%s\n", str4);



    return 0;
}

Hello
hello
world
weald

 

 

  • scanf string

scanf 로 입력할때 띄어쓰기나 엔터가 존재하면 입력의 종료로 인식하고 입력이 즉시 종료된다.

따라서 fgets()함수를 사용해 공백까지 입력을 받아야함.

#include <stdio.h>
//fgets() 함수를 사용하여 문자열을 입력받으면 공백 입력 가능
// 3번째 인자:stdin에서 입력을 받고 (우리가 입력하는 곳이 stdin이다. scanf함수가 정의되어 있는 곳이기도하다.)
// 1번째 인자: 지정한 버퍼에 입력을 저장
// 2번쨰 인자: 입력 받을 문자열의 최대 길이를 저장

int main(){

    char str[100];

    printf("enter string: ");
    //scanf("%s", str);  이때 scanf에서 띄어쓰기나 엔터는 입력의 종료로 인식함. test test입력시 test만 나온다.
    fgets(str, sizeof(str), stdin);
    printf("input string : %s\n", str);




    return 0;
}

enter string: test test     #공백 포함해 입력
input string : test test

 

 

#include <stdio.h>

int main(){

char name[20];
int age;

printf("이름을 입력하세요 : ");
scanf("%s", name);
while (getchar() != '\n'); // 입력 버퍼 비우기 (하나의 버퍼만 지우지 않고 \n이 나올때까지 버퍼를 지움. 모든 버퍼를 지우고 싶다면 이 반복문 작성)
//항상 이 getchar를 사용하는 것이 아니다. 입력 시에 값이 제대로 안나오면 사용하는것.
 
printf("나이를 입력하세요 : ");
scanf("%d", &age);
while (getchar() != '\n'); // 입력 버퍼 비우기

printf("이름은 %s, 나이는 %d살입니다",name, age);



    return 0;
}

이름을 입력하세요 : liam
나이를 입력하세요 : 53
이름은 liam, 나이는 53살입니다.

 

 

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

int main(){

    char str[100];

    printf("enter str: ");
    fgets(str, sizeof(str), stdin);

    int len = strlen(str); //문자열 바이트를 세어주는 함수. 가나다를 입력시 10바이트가 나오는거보면 이 컴퓨터에서는 한글을 3바이트로 입력받는다.
    printf("input str: %s", str);
    printf("length str: %d", len); // 입력한 문자 개수 + null문자

    // 컨트롤 키를 누른 상태에서 마우스를 갖다대면 변수나 함수의 원본으로 이동할 수 있음.





    return 0;
}

enter str: 리암갤러거
input str: 리암갤러거
length str: 16

 

 

 

  • string.h의 함수들:strstr

string.h는 문자열을 처리해주는 함수로 이 함수를 참조해야만 사용 가능한 함수들이 있다. 지금부터 어떤 함수들을 사용해 어떤 기능을 하는지 살펴보자.

//strstr(대상, 찾을값) -> 포인터(주소)를 리턴함.
// 즉 대상에서 찾을값을 찾는것임.
#include <stdio.h>
#include <string.h>

int main(){


    char str[100]= "the giraffe painting i drew is a hedgehog painting.";
    char substr[100] = "hedgehog" ;
    //h가 갖고 있는 주소값 result에 저장. str은 t를 가리키고 있는 주소 저장
    //그 둘을 빼면 몇번째 글자에 해당되는지 파악할 수 있을 것이다.(영어의 경우 1바이트. 한글의 경우2~3바이트)
    char * result =strstr(str,substr);
    printf("%p\n",result); // 실행할떄마다 매번 바뀜
    printf("%d %d\n",str, result); // 매번 바뀜

    if(result){     // result가 존재하면(substr에 str이 존재하면)
        printf("substr index: %d\n", result - str);
    } else {
        printf("not found.\n");
    }
   
    char * ptr_str = &str[33];
 
    printf("%s\n", ptr_str); //가능하면 printf("%s\n", &str[33]);보다 포인트를 활용해 출력할 수 있도록하자.
   

    return 0;
}

000000E4179FFA71
396360272 396360305
substr index: 33
hedgehog painting.

 

 

한글의 경우로도 해보자.

//strstr(대상, 찾을값) -> 포인터(주소)를 리턴함.
// 즉 대상에서 찾을값을 찾는것임.
#include <stdio.h>
#include <string.h>

int main(){


    char str[100]= "내가 그린 기린 그림은";
    char substr[100] = "기린" ;
    //h가 갖고 있는 주소값 result에 저장. str은 t를 가리키고 있는 주소 저장
    //그 둘을 빼면 몇번째 글자에 해당되는지 파악할 수 있을 것이다.(영어의 경우 1바이트. 한글의 경우2~3바이트)
    char * result =strstr(str,substr);
    printf("%p\n",result); // 매번 바뀜
    printf("%d %d\n",str, result); // 매번 바뀜

    if(result){
        printf("substr index: %d\n", result - str);
    } else {
        printf("not found.\n");
    }
   
    char * ptr_str = &str[14];
    printf("%s\n", ptr_str); //가능하면 포인트를 활용해 출력할 수 있도록하자.
   

    return 0;
}

0000004D3E3FFDAE
1044381088 1044381102
substr index: 14
기린 그림은

 

 

  • strcpy

copy 문자열에 복사된 모습을 확인할 수 있다.

  • strcmp

// 아스키 테이블을 보면 str1가 a일때 97, b일때 98이므로 str1이 cpp이고 str2가 banana일 때 1이 나오는 것이다.
// 만약 아얘 같은 글자 aa와 aa를 비교하면 0이 나오고 aa1과 aa2를 비교하면 -1이 나온다. 첫번째에서 두번째를 빼는 식임.

 

 

  • strcat

// strcat(대상, 붙일 값) 어디에다가 무엇을 붙일거냐 하는 코드
// 원본 데이터는 붙인 값으로 아얘 수정이 된다.

 

 

  • memset

// 배열을 복사할 때 반복문 또는 memcpy을 쓴다고 했었다.
// memcpy는 메모리의 구조를 복사하는 것이고
//memset은 초기화할 메모리값을 정하는 것이다.
// 기본적으로 메모리를 초기화할때 0의외의 값으로 전부 초기화 시키는 것은 불가능하다.
//int arr[5] ={1}을 하면 처음의 값만 1로 바뀌고 memset으로 1로 바꾸면 사진에 나오듯이 엉망의 값이 나온다.
// 이 때 우리가 원하는 int 1은 4byte단위의 1이 들어가야 하는데
// 이 함수에서 2번째 인자는 unsigned char로 들어감. 즉 1바이트씩 들어가는 것이며 1로 인자를 주면 1바이트씩 1이 들어간다.

 

따라서 1로 초기화를 해주고 싶으면 for문을 사용하면 된다.