[C Primer Plus] #4 문자열과 입출력 포맷

문연수·2022년 3월 7일
0

C Primer Plus

목록 보기
4/5
post-thumbnail

1. 복습 문제

- 1. 리스트 4.1(talkback.c) 을 다시 실행하라..

scanf()%s 서식 문자를 통해 문자열을 읽어 들일 때 공백을 기준으로 시작과 끝을 분리한다. 따라서 입력 버퍼에 문 연수 와 같은 형태로 데이터가 들어가게 되면 첫 번째 scanf() 을 읽고 다음 공백 문자에서 종료된다.
이후 몸무게를 입력받는 두 번째 scanf() 는 버퍼에서 읽어들인 데이터가 부동 소수점 수(연수 라는 입력 데이터는 +, -, ., 0-9 등의 수학 기호 혹은 수가 아님)가 아님을 확인하고 바로 즉시 반환되어 위와 같은 결과를 만들어낸다.

- 2. 아래의 각 예제들을 완전한 프로그램의 일부라고 가정하자.

* a

그는 그림을 $234.50에 팔았다.

* b

컴퓨터가 문자 표현 방식으로 ASCII 를 쓰고 있다면 아래와 같은 출력을 보인다.

Hi!

* c

strlen() 에 대한 서식 문자로 %zu 를 사용해야 한다.

그의 햄릿은 저속하지 않고 재미있었다.
는 53문자이다.

* d

1.20e+03 은 1201.00과 같으냐?

- 3. 문제 2c. 에서, 문자열 Q 를 큰 따옴표로 감싼 상태로 출력하려면 무엇을 변경해야 하는가?

#include <stdio.h>
#include <string.h>

#define Q "그의 햄릿은 저속하지 않고 재미있었다." 

int main(void)
{
	printf("\"%s\"\n는 %zu문자이다.\n", Q, strlen(Q));

	return 0;
}

- 4. 다음과 같은 프로그램에서 에러를 찾아라.

#include <stdio.h>

#define B "거짓말"
#define X 10

int main(void)
{
	int age;
	char name[BUFSIZ];
	int xp;

	printf("이름이 뭡니까?");
	scanf("%s", name);

	printf("좋아요, %s씨, 나이는 얼마죠?\n", name);
	scanf("%d", &age);

	xp = age + X;
	
	printf("%s! 최소한 %d세는 되어 보이는데.\n", B, xp);

	return 0;
}

- 5. 프로그램이 다음과 같이 시작한다고 가정하자.

#include <stdio.h>

#define BOOK "전쟁과 평화"

int main(void)
{
	float cost = 12.99;
	float percent = 80.0;

	printf("신간 \"%s\"를 $%2.2f 에 드립니다.\n"
	       "그것은 정가의 %2.0f%% 가격입니다.\n",
	       BOOK, cost, percent);

	return 0;
}

- 6. 다음의 각 내용을 출력하려면 어떤 변환 지정을 사용해야 하는가?

* a: %d

* b: %4X

* c: %10.3f

* d: %12.2e

* e: %-30s

- 7. 다음의 각 내용을 출력하려면 어떤 변환 지정을 사용해야 하는가?

* a: %15ul

* b: %#4x

* c: %-12.2E

* d: %+10.3f

* e: %8.8s

- 8. 다음의 각 내용을 출력하려면 어떤 변환 지정자를 사용해야 하는가?

* a: %6.4d

b: `%o`

* c: %2c

* d: %+0.2f

* e: %-7.5s

- 9. 다음과 같은 각 입력 라인에 대해, 그것을 읽는 scanf() 문을 작성하라.

* a

scanf("%d", &n);

* b

scanf("%f %E", &f1, &f2);

* c

scanf("%s", str);

* d

scanf("%d %d", &n1, &n2);

* e

scanf("%*s %d", &n);
printf("The double type is %zu bytes...", sizeof(double));

sizeof 연산자의 결과 자료형은 size_t 이다. 따라서 %zu 서식 지정자로 입력받는 것이 옳다.

- 10. 화이트스페이스란 무엇인가.

 공백, 개행, 탭 등의 사용자의 눈으로 식별 불가능한 문자.

- 11. 다음 문장에서 잘못된 점은 무엇이고, 이것을 어떻게 수정할 수 있을까?

- 12. 프로그램에서 중괄호 대신 괄호를 사용하려고 다음과 같이 정의했다고 가정하자. 어떤 일이 벌어지는가?

 함수 호출을 위해선 반드시 소괄호를 사용해야 하는데 이들이 모두 중괄호로 변환되어 문법 에러가 발생하게 된다.

2. 프로그래밍 연습

1.

#include <stdio.h>

#define LAST_NAME_LENGTH 30
#define FIRST_NAME_LENGTH 30

int main(void)
{
	char first_name[FIRST_NAME_LENGTH + 1];
	char last_name[LAST_NAME_LENGTH + 1];

	printf("last name: ");	scanf("%30s", last_name);
	printf("first name: ");	scanf("%30s", first_name);

	printf("%.*s %.*s\n", FIRST_NAME_LENGTH, first_name,
			      LAST_NAME_LENGTH, last_name);

	return 0;
}

2.

#include <stdio.h>
#include <string.h>

#define NAME_LENGTH 30

int main(void)
{
	char name[NAME_LENGTH + 1];

	printf("name: ");	scanf("%30s", name);

	printf("\"%s\"\n", name);
	printf("\"%20s\"\n", name);
	printf("\"%-20s\"\n", name);
	printf("%*s\n", (int) strlen(name), name);

	return 0;
}

3.

역대급 어려웠던 문제

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <stdbool.h>

void print_expo_leading_zero(char *fmt, double number, int leading)
{
	char buffer[13 + 10], *start, *end;
	int expo;

	snprintf(buffer, sizeof buffer, fmt, number);

	start = strchr(buffer, 'e');
	if (start == NULL)
		start = strchr(buffer, 'E');

	if (start) {
		expo = strtol(++start, &end, 10);
		snprintf(
			start, sizeof(buffer) - (end - start),
			"%0*d", leading, expo
		);
	}

	printf("%s", buffer);
}

int main(void)
{
	float number;

	scanf("%f", &number);

	printf("입력된 것은 %.1f 또는 ", number);
	print_expo_leading_zero("%.1e", number, 3); putchar('\n');

	return 0;
}

도움받은 사이트: https://stackoverflow.com/questions/31331723/how-to-control-the-number-of-exponent-digits-after-e-in-c-printf-e

4.

#include <stdio.h>

#define NAME_MAX 30

int main(void)
{
	char name[NAME_MAX];
	int height;

	printf("이름: ");	scanf("%s", name);
	printf("키: ");		scanf("%d", &height);

	printf("%s 씨, 당신의 키는 %.2f 미터입니다.\n",
		name, height / 100.0f);

	return 0;
}

5.

실제 문제는 메비바이트가 아닌 메가바이트 단위인데 필자가 임의로 바꿔서 계산해보았다.

#include <stdio.h>

double MiB_To_byte(double MiB)
{
	return MiB * 1024 * 1024;
}

double MBit_To_byte(double MBit)
{
	return MBit * 1.0E+6 / 8;
}

int main(void)
{
	double download_speed, filesize;

	printf("다운로드 속도(단위: Mbps): ");
	scanf("%lf", &download_speed);

	printf("파일 크기(단위: MiB): ");
	scanf("%lf", &filesize);

	printf("초당 %.2f MBps, %.2f MiB 파일을\n"
	       "%.2f 초에 다운로드 한다.\n",
	       download_speed, filesize, 
	       MiB_To_byte(filesize) / MBit_To_byte(download_speed));

	return 0;
}

6.

#include <stdio.h>
#include <string.h>

#define FIRST_NAME_LENGTH 30
#define LAST_NAME_LENGTH 30

int main(void)
{
	char first_name[FIRST_NAME_LENGTH],
	     last_name[LAST_NAME_LENGTH];
	int first_name_length, last_name_length;

	scanf("%s %s", first_name, last_name);

	first_name_length = strlen(first_name);
	last_name_length = strlen(last_name);

	printf("%s %s\n", first_name, last_name);
	printf("%*d %*d\n", first_name_length, first_name_length,
			    last_name_length, last_name_length);

	printf("%s %s\n", first_name, last_name);
	printf("%-*d %-*d\n", first_name_length, first_name_length,
			      last_name_length, last_name_length);


	return 0;
}

7.

#include <stdio.h>
#include <string.h>

int main(void)
{
	double d_var = 1.0 / 3.0;
	float f_var = 1.0f / 3.0f;

	printf("%.4f %.4f\n", d_var, f_var);
	printf("%.12f %.12f\n", d_var, f_var);
	printf("%.16f %.16f\n", d_var, f_var);

	return 0;
}

8.

#include <stdio.h>

#define MILE_PER_KILO		1.609
#define GALLON_PER_LITTER	3.785;

float mile_to_kilo(float mile)
{
	return mile * MILE_PER_KILO;
}

float gallon_to_litter(float gallon)
{
	return gallon * GALLON_PER_LITTER;
}

int main(void)
{
	float drive_distance;
	float used_gasolin;

	printf("주행거리(단위: mile): ");	scanf("%f", &drive_distance);
	printf("소비 휘발유(단위: gallon): ");	scanf("%f", &used_gasolin);

	printf("연비(마일 당 갤런): %.1f\n", drive_distance / used_gasolin);
	printf("연비(리터 당 100 킬로미터): %.1f\n",
		(gallon_to_litter(used_gasolin) * 100.0f)
	      / (mile_to_kilo(drive_distance))
	);

	return 0;
}
=
profile
2000.11.30

0개의 댓글