하만(Harman) 세미콘 아카데미 6일차 - SW 구조설계(문자와 문자열 처리 / 사용자 정의 함수 구현 )
semicon_designer
2024. 3. 14. 11:02
728x90
[2024.03.14.목] 인천인력개발원 하만 세미콘 아카데미
임베디드 시스템을 위한 SW 구조설계
문자와 문자열 처리 함수
C 표준함수
printf, scanf, getch등과 같이 기본적으로 제공되는 라이브러리
모든 플랫폼에 적용(getch는 windows만 지원)
호환성이 좋다 = 이식성이 높다
데이터 형식
기본 데이터 형식 - 문자 포함
사용자 정의 데이터 형식 - 구조체 등
문자열은 기본 데이터 형식과 사용자 정의 데이터 형식 사이
입출력의 이해
파일 / 콘솔 / 소켓 / serial port(COM port)에서의 입출력
파일: Data파일( binary / text ) 등 -> binary는 메모장에서 알아볼 수 없는 형태, text는 메모장에서 인식 가능한 글자로 표현
콘솔: 키보드(입력)+모니터(출력)
소켓: TCP/IP(통신 프로토콜)라이브러리 -> 이더넷(Ethernet) - 유/무선
UI(User Interface)
GUI(Graphical User Interface): 마우스를 기반으로 동작
스트림: 데이터 송수신을 위한 다리 / 입출력 흐름
표준 입/출력 스트림
C언어 기본 스트림 형태 - stdin: 표준 입력 스트림 / 입출력 장치: 키보드 (std: standard) - stdout: 표준 출력 스트림 / 입출력 장치: 모니터 - stdin: 표준 에러 스트림 / 입출력 장치: 모니터
문자 입출력 함수
출력 함수
int putchar(int c);
int fputc(int c, FILE* stream); //fputc 앞의 f는 파일을 의미, 뒤의 c는 char(문자)를 의미
- fuptc에서 FILE* stream을 stdin으로 설정하면 putchar과 같은 동작
입력 함수
int getchar();
int fgetc(FILE* stream);
- 1byte 입력 - fgetc에서 FILE* stream을 stdin으로 설정하면 getchar과 같은 동작
문자열 입출력 함수
출력 함수
int puts(const char* s);
int fputs(const char* s, FILE* stream); //fputc 앞의 f는 파일을 의미, 뒤의 s는 strubg(문자열)를 의미
- fputs에서 FILE* stream을 stdin으로 설정하면 puts과 같은 동작
입력 함수
char* gets(char* s);
char* fgets(char* s, int n, FILE* stream);
- gets: 입력받은 문자열을 저장할 공간 확보가 전제됨 - fgets: int n을 통해 입력받을 공간(buf영역)의 크기를 설정 -> n보다 큰 값이 입력되면 공간 크기에 맞는 부분까지만 입력 - fgets에서 FILE* stream을 stdin으로 설정하면 gets과 같은 동작
#include <string.h>
int strcmp(const char* s1, const char* s2);
int strncmp(const char* s1, const char* s2, size_t n);
return > 0 -> s1 > s2
return = 0 -> s1 = s2
return < 0 -> s1 < s2
첫 인수가 기준이 되어 비교
문자열 -> 숫자 변환 함수: 변환해야 할 자료형이 아닌 다른 자료형이 전달될 경우 에러 발생
#include <stdlib.h>
int atoi(char *ptr);// 문자열을 int형 데이터로 변환
long atol(char *ptr);// 문자열을 long형 데이터로 변환
float atof(char *str);// 문자열을 float형 데이터로 변환
- atoi: aschii to integer - atol: aschii to long - atof: aschii to float
대소문자 변환 함수
#include <ctypes.h>
int toupper(int c);// 소문자를 대문자로
int tolower(int c);// 대문자를 소문자로
실습 1: 문자열 길이 반환하는 length 함수 구현
[ 함수의 설계 ] - prototype 선언: void copy(char* p1), char* p2); - 함수명 : copy - 기능: p2문자열을 인수로 받아 p1문자열로 복사 - 인수: 타겟 문자열, 소스 문자열 (char* p1, char* p2) - 리턴 값: void(없음)
void test07(); test07함수 포로토타입 선언
함수의 길이를 반환할 int length(char* str); 함수 프로토타입 선언 => 문자열의 길이를 반환하므로 반환 자료형 int, 길이를 반환할 문자열이 인수로 들어가야 하므로 인수 char* str 사용
main함수 내의 메뉴를 추가하기 위해 pf배열에 test07을 요소로 추가
void* pf[] = { test01, test02, test03, test04, test05, test06, test07 };//type이 정해지지 않은 포인터 배열, 내부의 배열요소는 함수의 주소
main함수 내 while문에 7번을 선택할 수 있는 선택지 추가를 위한 printf함수 작성
while (1) {
printf("\n");
printf("1. 숫자키에 대한 문자열 출력\n");
printf("2. 문자열과 문자배열\n");
printf("3. 포인터의 위치 지정\n");
printf("4. 포인터를 이용한 문자열 입출력 함수\n");
printf("5. 구조체 테스트\n");
printf("6. 표준함수 테스트\n");
printf("7. 문자열의 길이 반환 함수 구현\n");
printf("0. 종료\n");
printf("=====================================\n > ");
scanf("%d", &n);
printf("\n");
if (n == 0) return; //0 입력 시 함수 종료
pfunc = pf[n - 1]; //배열은 0부터 시작하므로 1을 빼줌
pfunc(); //위에서 지정한 함수를 호출
}
- str 문자열을 설정하고, 이를 입력하기 위한 100byte의 안전공간 buf형성(필수!!) - printf를 통해 문자열 입력 칸 지정 - scanf를 통해 str에 문자열 입력 받음 - length함수를 통해 받은 문자열 길이 값을 len에 대입
length 함수 구현
int length(char *str) {
int len = 0;
while (*(str+len)) len++; //str의 len번째 글자가 null이 나올때까지 실행
return len;
}
- 입력된 인수 str의 문자열에 대해, while문 내에서 한 바이트씩 점검 - 한 바이트씩 넘어가다가 문자열의 값이 0이 나오면(null값 발견) while문 중지 및 현재까지의 길이 return
실행 확인 각 길이에 맞게 정상 출력 확인
교수님 코드 참고:
void test07(){
char buf[100];
printf("문자열을 입력하세요: "); scanf("%s", buf);
printf("입력한 문자열의 길이는 [%d]입니다.\n\n", length(buf));
}
int length(char* str){
int len = 0;
while(!){
if (*(str + len) == 0) break;
len++;
}
}
실습 2: 두 문자열을 비교하는 compare 함수 구현
두 개의 문자열을 인수로 받아 한 글자씩 비교하여 서로 다른 글자를 반환하는 함수 리턴 값: -1(str1 < str2), 0(str1 = str2), +1(str1 > str2) 1. 문자열을 비교할 실행 함수 test08 프로토타입 선언 void test08(); 2. 비교를 수행하는 사용자 정의 함수 선언 int compare(char* str1, char* str2); 3. main함수의 while문 안에 8번 메뉴로 문자열 비교 함수 구현 선택지 추가 printf("8. 문자열의 비교 함수 구현\n"); 4. 몇 번째 글자가 다른지 표기하기 위해 diffnum 정수형 변수 선언 5. test08함수 설정(int diffnum은 몇 번째 글자가 다른 지 파악하기 위한 변수) - 두 문자열이 같을 때와 다르면 어떤 위치에서 다른 지 표시
int diffnum;
void test08() {
char str1[100];
char str2[100];
int val;
printf("비교할 문자열을 입력하세요:\n");
printf("문자열 1: ");
scanf("%s", str1);
printf("\n문자열 2: ");
scanf("%s", str2);
val = compare(str1, str2);
printf("\n");
if (val == 0) printf("두 문자열이 같습니다.\n");
else if (val < 0) printf("문자열 1의 %c와 문자열 2의 %c가 %d번째에서 다릅니다. 문자열 1 문자 < 문자열 2 문자.\n", *(str1 + diffnum-1), *(str2 + diffnum-1), diffnum);
else if (val > 0) printf("문자열 1의 %c와 문자열 2의 %c가 %d번째에서 다릅니다. 문자열 1 문자 > 문자열 2 문자.\n", *(str1 + diffnum-1), *(str2 + diffnum-1), diffnum);
}
6. 비교를 위한 compare함수 설정
int compare(char* str1, char* str2) {
int comp = 0;
int i = 0;
while (comp == 0 ) {
if (*(str1 + i) == *(str2 + i)) comp = 0;
else if (*(str1 + i) < *(str2 + i)) comp = -1;
else if (*(str1 + i) > *(str2 + i)) comp = 1;
if ((*(str1 + i) || *(str2 + i)) == 0) break;
i++;
}
diffnum = i;
return comp;
}
7. 실행 화면
8. 사용한 전체 코드
#include <stdio.h>
#include <conio.h>
#include <string.h>
void test08(); //문자열을 비교하는 함수
int compare(char* str1, char* str2);
int main()
{
int n;
void* pf[] = { test01, test02, test03, test04, test05, test06, test07, test08 };//type이 정해지지 않은 포인터 배열, 내부의 배열요소는 함수의 주소
void (*pfunc)(); //return값이 없고 인자도 필요 없는 포인터 함수 선언
while (1) {
printf("\n");
printf("1. 숫자키에 대한 문자열 출력\n");
printf("2. 문자열과 문자배열\n");
printf("3. 포인터의 위치 지정\n");
printf("4. 포인터를 이용한 문자열 입출력 함수\n");
printf("5. 구조체 테스트\n");
printf("6. 표준함수 테스트\n");
printf("7. 문자열의 길이 반환 함수 구현\n");
printf("8. 문자열의 비교 함수 구현\n");
printf("0. 종료\n");
printf("=====================================\n > ");
scanf("%d", &n);
printf("\n");
if (n == 0) return; //0 입력 시 함수 종료
pfunc = pf[n - 1]; //배열은 0부터 시작하므로 1을 빼줌
pfunc(); //위에서 지정한 함수를 호출
}
}
int diffnum;
void test08() {
char str1[100];
char str2[100];
int val;
printf("비교할 문자열을 입력하세요:\n");
printf("문자열 1: ");
scanf("%s", str1);
printf("\n문자열 2: ");
scanf("%s", str2);
val = compare(str1, str2);
printf("\n");
if (val == 0) printf("두 문자열이 같습니다.\n");
else if (val < 0) printf("문자열 1의 %c와 문자열 2의 %c가 %d번째에서 다릅니다. 문자열 1 문자 < 문자열 2 문자.\n", *(str1 + diffnum - 1), *(str2 + diffnum - 1), diffnum);
else if (val > 0) printf("문자열 1의 %c와 문자열 2의 %c가 %d번째에서 다릅니다. 문자열 1 문자 > 문자열 2 문자.\n", *(str1 + diffnum - 1), *(str2 + diffnum - 1), diffnum);
}
int compare(char* str1, char* str2) {
int comp = 0;
int i = 0;
while (comp == 0) {
if (*(str1 + i) == *(str2 + i)) comp = 0;
else if (*(str1 + i) < *(str2 + i)) comp = -1;
else if (*(str1 + i) > *(str2 + i)) comp = 1;
if ((*(str1 + i) || *(str2 + i)) == 0) break;
i++;
}
diffnum = i;
return comp;
}