C언어 포인터로 문자열 제어하기
< 코드 결과 사진 >
코드 개요
본 코드는 C언어 문자열을 포인터로 제어해보는 코드입니다.
입력받은 문자열을 모두 대문자, 소문자로 만들거나 문자열을 거꾸로 만들어주는 프로그램입니다.
작업 환경
처음에는 Mac OS X 환경에서 코드를 작성하고 테스트하였습니다.
Windows의 Visual Studio 2017 IDE로 빌드 결과 문자열 리터럴 부분에서 타입 오류가 났습니다.
그래서, myStrCopy(char*, char*) 함수의 시그니쳐를 myStrCopy(char*, const char*) 으로 변경하였습니다.
디버그시 scanf의 보안 이슈 알림을 중지하려고 소스 코드 상단에 _CRT_NO_SECURE_WARNINGS 매크로 넣었습니다.
원본 질문
본 질문은 N사의 지식인에 올라온 질문입니다. 원본 질문은 아래와 같습니다.
키보드로 문자열 입력받아 출력하는 코드인데요
[입력화면]
문자열을 입력하세요:
1)문자열을 모두 대문자로 출력하세요.
2)문자열을 모두 소문자로 출력하세요.
3)문자열을 거꾸로 출력하세요.
4)원본을 그대로 출력하세요.
5)프로그램을 종료합니다.
출력메뉴를 선택하세요:
[출력화면]
원본데이터는 [...]이고, [대문자or소문자or거꾸로or원본으]로 [...]입니다.
(or프로그램을 종료합니다.)
너무 코드가 길고 복잡해서 짜도 오류만 계속 뜹니다 ㅠㅠ
주석달아서 코드좀 짜주세요
reverse나 그런 라이브러리 쓰면 안됩니다.
배열이나 기본적인 명령어를 통해 짜야합니다 ㅠㅠ
내공 드립니다ㅠㅠ 내공 드립니다
출처 : https://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=324869671
프로그램 코드
프로그램 코드는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | // Written by Chipmunk, 2019 / 04 / 09 // Web site : https://itchipmunk.tistory.com #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> // 기본 문자열 크기 #define BUFFER_SIZE 1024 // 메뉴 열거 enum PRINT_MENU { PRINT_UPPER = 1 , PRINT_LOWER , PRINT_REVERSE , PRINT_ORIGINAL , EXIT }; // 문자열 복사 함수 void myStrCopy(char* dest, const char* source); // 프로그램 함수 char* InputStringMenu(); void OutputMenu(char* inputStr); void Execute(int choice, char* inputStr); // 기능 함수 char* GetUpper(char* source); char* GetLower(char* source); char* GetReverse(char* source); char* GetOriginal(char* source); int main(int argc, char* argv[]) { char* inputStr = InputStringMenu(); OutputMenu(inputStr); return 0; } char* InputStringMenu() { char* str = 0; char* tmpStr = 0; str = (char*)malloc(BUFFER_SIZE); // BUFFER_SIZE 만큼 메모리 주소를 할당하고 그 주소를 담음 // 개행 포함 한 줄을 읽음 do { printf("[입력화면]\n문자열을 입력하세요: "); } while (fgets(str, BUFFER_SIZE, stdin) == 0); // 마지막 개행을 지워줌 for (tmpStr = str; *tmpStr != '\n'; tmpStr++); *tmpStr = '\0'; return str; } void OutputMenu(char* inputStr) { assert(inputStr != 0); int choice = 0; // 메뉴 출력 printf("%d) 문자열을 모두 대문자로 출력하세요.\n", PRINT_UPPER); printf("%d) 문자열을 모두 소문자로 출력하세요.\n", PRINT_LOWER); printf("%d) 문자열을 거꾸로 출력하세요.\n", PRINT_REVERSE); printf("%d) 원본을 그대로 출력하세요.\n", PRINT_ORIGINAL); printf("%d) 프로그램을 종료합니다.\n\n", EXIT); // 유효한 메뉴를 받을 때까지 반복 while (choice < 1 || choice > 5) { printf("출력메뉴를 선택하세요:"); scanf("%d", &choice); } // 실행 함수에 메뉴와 입력 문자열 전달 Execute(choice, inputStr); } void Execute(int choice, char* inputStr) { assert(choice >= PRINT_UPPER && choice <= EXIT); assert(inputStr != 0); char* outputStr = 0; char typeStr[20] = {}; // 전달 받은 메뉴에 따라 기능 함수 실행 switch (choice) { case PRINT_UPPER: myStrCopy(typeStr, "대문자"); outputStr = GetUpper(inputStr); break; case PRINT_LOWER: myStrCopy(typeStr, "소문자"); outputStr = GetLower(inputStr); break; case PRINT_REVERSE: myStrCopy(typeStr, "거꾸로"); outputStr = GetReverse(inputStr); break; case PRINT_ORIGINAL: myStrCopy(typeStr, "원본으"); outputStr = GetOriginal(inputStr); break; case EXIT: printf("프로그램을 종료합니다.\n"); // 원본 데이터 메모리 공간 해제 free(inputStr); return; break; } // 결과 출력 printf("원본 데이터는 \"%s\"이고, %s로 \"%s\" 입니다.\n" , inputStr , typeStr , outputStr ); // 원본 데이터, 출력 데이터 메모리 공간 해제 free(inputStr); free(outputStr); } char* GetUpper(char* source) { assert(source != 0); char* dest = 0; dest = (char*)malloc(BUFFER_SIZE); // 대상문자열의 주소 위치를 보존하기 위해 변경되는 주소를 담을 변수 생성 char* tmpDest = dest; // 원본 문자열을 끝까지 돌며, 대상 문자열에 저장 for (; *source != '\0'; source++, tmpDest++) { // 소문자인지 확인 if (*source >= 'a' && *source <= 'z') { // 'a' 아스키 코드와의 차이를 'A' 아스키 코드에 더함 *tmpDest = 'A' + (*source - 'a'); } else { // 그 외에는 그대로 저장 *tmpDest = *source; } } // 대상 문자열의 마지막에 널문자 추가 *tmpDest = '\0'; return dest; } char* GetLower(char* source) { assert(source != 0); char* dest = 0; dest = (char*)malloc(BUFFER_SIZE); // 대상문자열의 주소 위치를 보존하기 위해 변경되는 주소를 담을 변수 생성 char* tmpDest = dest; // 원본 문자열을 끝까지 돌며, 대상 문자열에 저장 for (; *source != '\0'; source++, tmpDest++) { // 대문자인지 확인 if (*source >= 'A' && *source <= 'Z') { // 'A' 아스키 코드와의 차이를 'a' 아스키 코드에 더함 *tmpDest = 'a' + (*source - 'A'); } else { // 그 외에는 그대로 저장 *tmpDest = *source; } } // 대상 문자열의 마지막에 널문자 추가 *tmpDest = '\0'; return dest; } char* GetReverse(char* source) { assert(source != 0); char* dest = 0; char* endInputStr = 0; dest = (char*)malloc(BUFFER_SIZE); // 원본과 대상문자열의 주소 위치를 보존하기 위해 변경되는 주소를 담을 변수 생성 char* tmpSource = source; char* tmpDest = dest; // 임시 문자열의 위치를 마지막으로 옮김 for (; *tmpSource != '\0'; tmpSource++) { } // 널문자 바로 앞으로 이동한 주소를 저장 endInputStr = tmpSource - 1; // 원본 문자열의 주소 위치까지 되돌아가며 대상 문자열에 저장 for (; endInputStr >= source; endInputStr--, tmpDest++) { *tmpDest = *endInputStr; } // 대상 문자열의 마지막에 널문자 추가 *tmpDest = '\0'; return dest; } char* GetOriginal(char* source) { assert(source != 0); // 원본 문자열을 전부 복사하여 반환 char* dest = 0; dest = (char*)malloc(BUFFER_SIZE); myStrCopy(dest, source); return dest; } void myStrCopy(char* dest, const char* source) { assert(dest != 0); assert(source != 0); // 원본 문자열의 끝까지 돌며, 대상 문자열에 복사 for (; *source != '\0'; source++, dest++) { *dest = *source; } // 대상 문자열의 마지막에 널문자 추가 *dest = '\0'; } | cs |