C - 문자열 연습
C언어를 주제로 한 일곱번째 포스팅은 문자열에 대하여 다루어보겠습니다.
지금까지 여러가지 배열의 선언과 그배열을 활용하는예제들을 통해 스터디하였습니다. 하지만 지금까지는 모두 숫자에 관련된
변수타입을 다루었습니다. 이번엔 문자형 데이터 타입인 char형으로 이루어진 문자열에 대하여 스터디하겠습니다.
C 예제문제 8번 - 다음의 조건을 만족하는 프로그램을 작성하시오.
두 줄의 문장을 입력받기 (line1[], line2[])... gets 사용
line1과 line2에 입력받은 문자 수 구하기
count_chars() 함수 만들어 사용하기
해결 과정)
Step1) gets 함수를 이용하여 line1,line2스트링배열 초기화하기
먼저 메인함수 내에서 스트링배열 line1과 line2를 크기 [50]으로 선언하였습니다.
char line1[50];
char line2[50];
그리고 p.506의 예제를 참고하여 gets()함수를 사용하였습니다.
각각의 스트링을 초기화후 화면에 한번 출력하였습니다.
printf("line1 입력\n");
while (gets(line1))
printf("입력된 문자열 : %s", line1);
printf("\n");
printf("line2 입력\n");
while (gets(line2))
printf("입력된 문자열 : %s", line2);
Step2) 초기화된 스트링을 매개변수로 받아 입력받은 문자수를 구하는 count_char 함수 선언하기
매개변수로 스트링을 하나 받아들이고 리턴타입은 정수형으로 잡았습니다.
int count_chars(char string[]) {…}
스트링구조를 이용하여 제일 마지막에 포함되는 ‘\0’가 나올때까지 조건검사를 수행하였습니다.
이해를 돕기 위해 그림을 하나 첨부하겠습니다.
String[i++]를 통해 배열의 옆방으로 이동하며 char의 내용이 ‘\0’가 나올때까지 카운트를 올려주며 반복합니다
while (string[i++]!='\0')
{
cnt++;
}
return cnt;
만약 ‘\n’을 만난다면 반복문을 실행하지 않고 그때의 cnt값이 매개변수가 입력받은 문자의 수가 됩니다
코드와 결과화면은 예제 9번과 함께 제일 마지막에 첨부하겠습니다.
C 예제문제 9번 -두 줄의 문장을 하나로 연결시키기.
add_two_lines() 함수를 만들어 사용할 것.
해결 과정)
Step1) add_two_lines() 의 리턴타입 정하기.
저는 처음 이 함수의 리턴타입으로 char를 사용하려고 했습니다. 하지만char타입의 변수를 하나만 리턴하는 것이 아닌 두개의 스트링을 합친 새로운 스트링을 리턴해야했었음으로 이방법은 컴파일오류는없지만 원하는 실행결과를 가져올수없었습니다.
그래서 두개의 스트링을 합친 결과물 스트링을 만들고 그것을 저장한 주소값을 리턴하여 출력하면 메인함수에서 원하는 결과를 얻을 수 있다는 결론이 나왔습니다.
배열은 자체가 포인터처럼 사용가능하기 때문에 주소연산자(&)없이 리턴해주었고 함수의 타입선언은 char형의 포인터 변수로 선언하였습니다.
“p.367,(void *)는 아직 결정되지 않은 자료형의 주소를 나타낸다” 여기서 힌트를 얻었습니다.
char* add_two_lines(char line1[], char line2[]){
…
Return line1;
}
Step2) 두개의 스트링을 연결해줄 방법 구상하기
두스트링을 연결하기 위해서 교수님이 제시하여주신 두가지 방법중에 저는 후자인 line1 뒤에 line2를 이어 붙이는 방법을 택하였습니다.
Line1에서 사용된 문자들의 갯수만큼보다 뒤에 인덱스에서 line2를 복사하였고 저는 Line1에서 사용된 문자들의 개수 를 용량을 뜻하는 capacity라는 이름의 변수로 선언하였습니다.
char* add_two_lines(char line1[], char line2[]) {
int capacity = 0; int i = 0; // line1's capacity
while (line1[i] != '\0')
{
capacity++;
i++;
}
Line1배열을 돌며 ‘\0’가 나오기전까지 카운팅하여 capacity를 올려주었고 이렇게 초기화된 capacity만큼보다 뒷인덱스에서 line2가 시작되게 코딩하였습니다.
Line2의 첫번째 인덱스부터 복사하기위해 i를 0으로 초기화해주고 복사를 진행하였습니다.
i = 0;
while (line2[i] != '\0')
{
line1[capacity + i] = line2[i];
i++;
}
그리고 다 만들어진 char배열을 %s로 찍을수 있는 스트링 문자열의 형태로 완성해주기위해
line1[capacity + i] = '\0';
제일마지막 인덱스에 ‘\0’로 초기화하여 주었고 그대로 완성된배열을 char포인터 타입으로 리턴하여주었습니다.
char* add_two_lines(char line1[], char line2[]) {
…
…
return line1;
}
마지막으로 메인함수 내에서 함수들을 불러와서 사용하는 것으로 코딩을 마무리하였습니다.
int main(void) {
…
…
printf("\n<과제 1번 문장에 포함된 글자수 출력");
printf("\nline1 : %d\nline2 : %d\n",count_chars(line1), count_chars(line2));
printf("\n<과제 2번 문장 2개 이어붙이기\n");
printf("%s", add_two_lines(line1,line2));
return 0;
}
전체 코드)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<conio.h>
int count_chars(char string[]) {
int cnt = 0;
int i = 0;
while (string[i]!='\0')
{
cnt++;
i++;
}
return cnt;
}
char* add_two_lines(char line1[], char line2[]) {
int capacity = 0; int i = 0; // line1's capacity
while (line1[i] != '\0')
{
capacity++;
i++;
}
i = 0;
while (line2[i] != '\0')
{
line1[capacity + i] = line2[i];
i++;
}
line1[capacity + i] = '\0';
return line1;
}
int main(void) {
char line1[50];
char line2[50];
printf("line1 입력\n");
while (gets(line1))
printf("입력된 문자열 : %s", line1);
printf("\n");
printf("line2 입력\n");
while (gets(line2))
printf("입력된 문자열 : %s", line2);
printf("\n<과제 1번 문장에 포함된 글자수 출력");
printf("\nline1 : %d\nline2 : %d\n",count_chars(line1), count_chars(line2));
printf("\n<과제 2번 문장 2개 이어붙이기\n");
printf("%s", add_two_lines(line1,line2));
return 0;
}
결과 콘솔)