c로 배우는 자료구조 - 문자열

1. 문자열

  • 문자열은 char타입의 배열의 각 칸마다 문자 하나씩 저장됨
  • null character(‘\0’)는 문자열의 끝을 표시하는 역할을 한다. 즉 배열의 크기가 문자열의 길이보자 적어도 1만큼 길어야 한다.

C 언어는 문자열을 생성하는 편리한 방법을 제공한다.

char str[] = "hello";
혹은

char *str = "hello";
이렇게 정의된 문자열은 수정이 불가능하다는 점에서 위의 두 방법과 다르다. 이것을 string literal이라고 부른다

길이가 6byte에 메모리 공간이 할당되고 그 배열의 시작주소를 리턴해주면 그것을 포인터변수 str에 저장하는 것이므로 결과적으로 동일하다.
이 경우는 str이 hello가 아닌 새로운 문자열을 가리키도록 할 수 있찌만

맨 위 str[]의 경우 str이 다른 배열을 가리키도록 할 수 없다.

2. string.h 라이브러리

  • strcpy - 문자열 복사
  • strlen - 문자열 길이
  • strcat - 문자열 합치기
  • strcmp - 문자열 비교

3. 문자열들의 저장 예제

datastructure 2


#include...
# define BUFFER_SIZE 100
int main(){
	
    char *words[100];
    (각각의 한 칸에 저장되는 타입이 배열의 타입)
    (누군가의 주소를 넣을 것이기 때문에 포인터 변수)
    int n = 0; // number of strings
    char buffer[BUFFER_SIZE];
    
    while(scanf("%s",buffer) !=EOF ){
		words[n] = buffer;
        n++;
	} 
// scanf("%d",&a)(주소를 추출하는 연산자 &) 여기서는 배열의 이름이 실제 그 배열의 주소를 저장하고 있는 포인터 변수이기 떄문이다. 
// EOF는 파일의 끝을 의미한다.
    
    printf("%s", word);

}

이 코드를 이렇게 작성하면 문제가 발생한다


#include...
# define BUFFER_SIZE 100
int main(){
	
    char *words[100];
    int n = 0; // number of strings
    char buffer[BUFFER_SIZE];
    
    while(n<4 && scanf("%s",buffer) !=EOF ){
		words[n] = buffer;
        n++;
	} 
    
    for (int i=0; i<4; i++)
    	printf("%s", word[i]);

}

입력값 
sdjfh
dsfhd
jdhsfj
sdfsdf

결과값
sdfsdf
sdfsdf
sdfsdf
sdfsdf

words[n]에 buffer;를 대입. 이 치환 문은 두 개의 포인터 변수들 간의 치환문이다. 포인터 변수 간에 치환을 하게 되면, 이 식의 오른쪽에 있는 값을 왼쪽에 쓰는 거니까. buffer가 가진 포인터 값을 words[n]에 넣는 것이다.

while 문을 돌고 다시 쓰게 되면, 똑같은 buffer에 다시 갱신되므로 처음에 넣은 값이 지워진다.

그럼 어떻게 카피를 해야할 까?


#include...
# define BUFFER_SIZE 100
int main(){
	
    char *words[100];
    int n = 0; // number of strings
    char buffer[BUFFER_SIZE];
    
    
    while(n<4 && scanf("%s",buffer) !=EOF ){
		words[n] = strdup(buffer); //strcpy(str2,str1) str1을 str2로 복사하는 이 방향. 뒤에 것을 앞으로
//strdup: strcpy가 이 문자열을 이렇게 카피해주는 것 인데, strdup는 매개변수로 하나의 문자열을 받아서, 이 문자열의 복제본을 만들어서 이 복제본의 주소를 리턴해주는 역할을 한다. 
        n++;
	} 
    
    for (int i=0; i<4; i++)
    	printf("%s", word[i]);

}

4. 문자열 복사 : strdup

char & strdup(char *s)
{

	char *p;
    p = (char *)malloc(strlen(s)+1);
    if (p != NULL)
    	strcpy(p,s);
    return p;
}

5. 파일 읽기, 쓰기

#include <stdio.h>

void main(){
	FILE * fp = fopen("input.txt", "r");
    char  buffer[100];
    while (fscanf(fp, "%s", buffer) != EOF)
		printf("%s", buffer);
    fclose(fp);
}

#include <stdio.h>

void main(){
	FILE * in_fp = fopen("input.txt", "r");
    FILE * out_fp = fopen("output.txt", "w");
    char buffer[100];
    while (fscanf(in_fp, "%s", buffer) != EOF)
    fprintf(out_fp, "%s", buffer);
    fclose(in_fp);
    fclose(out_fp);

}


참고자료

동영상 주소

0%