문제 1.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(void) {
char buffer[40];
while (1) {
printf("$ ");
//scanf("%s", buffer); // scanf는 공백 기준으로 나누므로 우리가 원하는 게 아니다.
fgets(buffer,10,stdin); // gets는 라인별로 입력받는다. but 코드가 안정하지 않다.
printf("%s:%d\n", buffer, strlen(buffer));
}
return 0;
}
=============================
$ adfdfas
adfdfas
:8
위의 코드의 출력값을 보면 adfdfas : 8이 위 아래로 띄어쓰기 되어 있는데 이는 우리가 원하는것이 아니다. 이러한 현상이 발생하는 이유는 fgets 함수는 우리가 adfdfas를 입력하고 엔터를 눌를때 그 엔터까지 buffer에 저장하기 때문입니다. 즉, 줄바꿈 문자까지 포함해버리는 문제가 발생합니다. (gets함수는 그렇지 않습니다.)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(void) {
char buffer[40];
while (1) {
printf("$ ");
//scanf("%s", buffer); // scanf는 공백 기준으로 나누므로 우리가 원하는 게 아니다.
fgets(buffer,10,stdin); // gets는 라인별로 입력받는다. but 코드가 안정하지 않다.
buffer[strlen(buffer)-1] = '\0';
printf("%s:%d\n", buffer, strlen(buffer));
}
return 0;
}
buffer의 마지막을 제외해주면 우리가 원하는 값을 얻을 수 있습니다. 하지만 이도 우리가 원하는 값을 완벽히 도출하지는 않습니다. 만약 입력값이 buffer길이를 초과할때 buffer보다 초과된 문자열은 무시하고 싶지만 이는 그렇게 되지 않습니다.
함수를 만들어 우리가 원하는 값이 도출되도록 합니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int read_line(char str[], int limit);
int main(void) {
char buffer[40];
while (1) {
printf("$ ");
//scanf("%s", buffer); // scanf는 공백 기준으로 나누므로 우리가 원하는 게 아니다.
// fgets(buffer,10,stdin); // gets는 라인별로 입력받는다. but 코드가 안정하지 않다.
//buffer[strlen(buffer)-1] = '\0';
read_line(buffer, 40);
printf("%s:%d\n", buffer, strlen(buffer));
}
return 0;
}
int read_line(char str[], int limit) {
int ch, i = 0;
while ((ch = getchar()) != '\n') // 한글자를 읽어 ch로 하자
if (i < limit-1)
str[i++] = ch; // str[i]에 ch 저장하고 i를 1 증가 시킨다.
str[i] = '\0';
return i;
}
문제2.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int read_line_with_compression(char compressed[], int limit);
int main(void) {
char line[80];
while (1) {
printf("$ ");
int length = read_line_with_compression(line, 80);
printf("%s:%d\n", line, length);
}
return 0;
}
int read_line_with_compression(char compressed[], int limit) {
int ch, i = 0;
while ((ch = getchar()) != '\n') {
if (i < limit - 1 && (!isspace(ch) || i > 0 && !isspace(compressed[i - 1])))
compressed[i++] = ch;
}
if (i > 0 && isspace(compressed[i - 1]))
i--;
compressed[i] = '\0';
return i;
}
불필요한 공백과 필요한 공백을 구분하는 것이 이문제의 중요한 조건입니다.
- while ((ch = getchar()) != '\n')
이 조건은 getchar()로 한글자씩 읽어서 ch에 저장하고 줄바꿈 문자인 \n를 만나기 전까지 즉 한라인을 읽어 들이는 조건입니다.
- if (i < limit - 1 && (!isspace(ch) || i > 0 && !isspace(compressed[i - 1])))
i가0보다 크면서 새로만든compressed[i-1]칸이 공백이 아니거나, 현재ch가 공백이 아닐때,
동시에 compressed배열의 index를 가리키는 i가 배열의 크기를 초과하지 않을때, compressed배열에 ch를 추가하고 i를 1 더합니다.
이조건을 사용하면 문자 시작 전 공백과 문자와 문자사이의 불필요한 공백을 없앨 수 있습니다. 하지만 아직 문제가 남아 있습니다. 문자가 끝난 후 공백에서 발생하는데, 마지막 줄바꿈 문자'\n'에 다다를때, 우리눈에는 공백이지만 컴퓨터에서는 공백으로 인식하지 않아 맨 마지막에 불필요한 공백이 하나 더 생깁니다. 이를 해결하기 위해 다음 조건을 사용합니다.
if (i > 0 && isspace(compressed[i - 1]))
이 조건을 사용해 해결하는데, compressed배열에서 특정 인덱스를 가리키는i 바로 앞 칸이 공백이면 불필요한 공백이 생긴 것이므로, i를 하나 줄여줘 최종 i값을 리턴합니다.
'Language > 자료구조' 카테고리의 다른 글
[5] C review < 전화번호부 알고리즘 version2.0 > (0) | 2021.11.22 |
---|---|
[4] C review < 전화번호부 알고리즘 version1.0 > (0) | 2021.11.22 |
[2] C review < 문자열 > (0) | 2021.11.15 |
[1] C review < 동적메모리 할당 > (0) | 2021.11.15 |
[0] C review < 포인터,배열,포인터 연산 > (0) | 2021.11.15 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!