Chapter 11

GraGrass·2024년 2월 13일

입출력

Standard I/O

1. printf()

서식 문자

int printf(Control-string, item1, item2, ...);
서식 문자출력 형태
%c단일 문자 char
%d(%i)signed 10진 정수
%f실수 float
%s문자열 string
%ounsigned 8진 정수 octal
%p포인터 pointer
%x, %Xunsigned 16진 정수 heXadecimal
%e, %Ee(E) 표기법에 의한 실수
%g, %G값에 따라 %f, %e(E) 중 선택
%%% 기호 출력

특수 문자

특수 문자의미
\b백스페이스
\n개행 (enter)
\t수평 탭
\\백슬래시 ()
\'작은 따옴표
\"큰 따옴표

printf()의 return값

  • printf() 함수는 자신이 출력한 문자 수를 반환
  • 출력 에러 발생 시, 음수 반환
  • 반환값을 사용하는 사례는 많이 없음

긴 문자열의 출력

#include <stdio.h>

int main() {
	char* str = "programming language.";
	printf("C is powerful"
		" general-purpose %s" "\n",
		str);
	return 0;

}
  • C는 요소들을 분리하는 용도 외에는 스페이스, 탭, 개행(화이트 스페이스) 무시
  • 하나의 문장을 여러 라인에 나누어 써도 무방
#include <stdio.h>

int main() {
	int rv = 10;
	printf("The prinf() functiond printed %d
		characters.\n", rv);
	return 0;
}

// Compile error 발생!!
  • 큰따옴표로 묶여있는 문자열은 중간에 분리 불가
  • 개행문자를 나타내기 위해 문자열이 '\n' 사용 가능
#include <stdio.h>

int main() {
	printf("C is a powerful \
	general-purpose \
programming language. \
\n");
	return 0;
}

  • 큰따옴표 안의 내용을 나누어 쓸 때에는 활용
  • 다음 라인은 반드시 첫칸부터 시작해야하며, 들여쓰기 시 \t도 출력 string의 일부가 됨

2. scanf()

입력 형태

  • printf()의 서식 문자를 그대로 사용

실수 입력 시 주의사항

  • 실수를 입력 받기 위해 %f or %e 사용
  • 입력 받는 실수의 소수점 이하 자리수가 6자리를 넘지 않으면 %f, 넘어가면 %e 사용

개요

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int age;
	float pi;
	char str[30];

	scanf("%d %f %s", &age, &pi, str);
	printf("%d, %f, %s\n", age, pi, str);
	return 0;
}

  • string 입력을 다양한 포맷으로 변환
  • printf()의 역함수와 비슷한 역할
  • 함수의 format string과 input string의 형태가 정확히 일치해야 읽어들일 수 있음

매개변수

  • scanf()printf()와 마찬가지로 포맷 문자열 + 전달 인자 리스트 사용
  • 포맷 문자열은 문자열들의 입력 스트림을 변환할 데이터 형들로 지시
  • scanf() 함수는 scan한 내용을 전달할 매개변수로 포인터 사용 (call by reference)

화이트 스페이스

  • scanf() 함수는 사용자의 입력을 개별 필드로 나누기 위해 화이트 스페이스 사용
  • 중간에 있는 화이트 스페이스는 건너 뒤면서, 연속된 변환 지정자들을 연속된 필드에 각각 연결시킴
  • 단, %c 지정자는 화이트 스페이스를 그대로 읽어들임

반환값

  • scanf() 함수는 성공적으로 읽은 항목의 수를 return
  • 읽은 항목이 없을 때에는 0 반환
  • 파일의 끝이라고 알려진 어떤 조건을 만날 시 EOF(End Of File) 반환

3. printf와 scanf에서의 * 변경자

printf()에서의 * 변경자

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int width, precision;
	int n = 245;
	double d = 242.5;
	scanf("%d", &width);
	printf("n: |%*d|\n", width, n);

	scanf("%d %d", &width, &precision);
	printf("d= |%*.*lf|\n", width, precision, d);
}

  • 필드 폭을 동적으로 지정할 수 있게 해줌

scanf()에서의 * 변경자

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int n1 = 0, n2 = 0, n3 = 0;
	scanf("%d %d %d", &n1, &n2, &n3);
	printf("%d %d %d\n", n1,n2,n3 );
	n1 = 0, n2 = 0, n3 = 0;
	scanf("%*d %*d %d", &n3);
	printf("%d %d %d\n", n1, n2, n3);
	return 0;
}

  • %와 지정문자 사이에 *를 넣으면 scanf()가 그에 해당하는 입력을 건너 뜀
  • 데이터가 일정한 형식으로 정렬되어 있는 파일에서 하나의 특정한 열을 읽을 필요가 있을 때 유용하게 사용

File I/O

1. 파일의 개방(Open)

개요

  • 표준 I/O장치의 데이터 I/O를 위한 스트림은 프로그램 시작 시 OS에 의 해 기본적으로 생성
  • 파일의 데이터 I/O를 위한 스트림은 직접 생성&소멸시켜야 함

파일의 개방

  • 파일로부터 데이터를 I/O 하려면 제일 먼저 파일을 열어야 함
  • 파일의 개방 == 파일과 데이터를 주고 받을 수 있는 스트림 생성
  • 데이터 I/O 모드: t(텍스트 모드, default) / b(2진 모드)

스트림(키보드/모니터, 파일)

기능/스트림표준(키보드, 모니터)선택(키보드/모니터, 파일)
문자 출력int putchar(int c)int fputc(int c, FILE* stream)
문자 입력int getchar(void)int fgetc(FILE* stream)
문자열 출력int puts(const char* s)int fputs(const char* s, FILE* stream)
문자열 입력char *gets(char*s)char *fgets(char*s, int n, FILE* stream)
형식 지정 출력int printf(const *format, ...)int fprintf(FILE* stream, const *format, ...)
형식 지정 입력int scanf(const *format, ...)int fscanf(FILE* stream, const *format, ...)

fopen()

#include <stdio.h>

FILE *fopen(const char *filename, const char *mode);
FILE *f = fopen("c:\\work\\test.dat", "rt");
  • 성공 시 해당 파일의 포인터, 실패 시 NULL 포인터 return
  • *filename: 파일의 이름과 경로 정보를 지니는 string
  • *mode: 개방 모드(open mode)를 나타내는 string

2. 파일 접근 모드

r

  • 파일을 읽기 위해 개방, 오로지 읽는 것만 가능

w

  • 데이터를 쓰기 위해 개방, 오로지 쓰는 것만 가능
  • fopen함수 호출 시 지정된 파일이 존재하지 않으면 , 새로운 파일 생성 후 데이터 입력
  • 지정된 파일 존재 시 그 파일의 데이터를 지우고 데이터를 쓰게 됨

a

  • w 모드와 달리, 지정된 파일이 존재하면 지우기 않고 파일의 끝에서부터 데이터 추가
  • 나머지 특징은 w 모드와 동일

3. 파일의 종결(Close)

fclose()

#include <stdio.h>
int fclose(FILE *stream);
  • 종료가 오류 없이 제대로 이뤄지면 0 return

리턴값 참조 방법

함수파일 끝에서 return되는 값
fgetcEOF(-1)
fgetsNULL 포인터(0)
fscanfEOF(-1)
while(1){
	pState=fgets(str, sizeof(str), file);
    if (pState == NULL) break; // fgets()는 파일의 끝에서 NULL return
    fputs(str, stdout); // 파일 내용 모니터에 출력
}
  • 파일로부터 데이터를 읽어들이는 함수들은 파일의 끝에 도달하는 경우 정해진 값을 return
  • 이 값을 참조하여 파일의 끝 구분 가능

4. fread() , fwrite()

개요

  • fprintf()로 출력하는 경우 숫자는 문자열로 출력됨
  • 가장 정확하고 일관되게 수를 저장하는 방법은, 프로그램이 사용하는 비트 패턴과 동일한 비트 패턴을 사용하는 것
  • 프로그램이 사용하는 표현과 동일한 표현으로 데이터를 파일에 저장할 때, 그 데이터가 binary form으로 저장되었다 함

사용

#include <stdio.h>

size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE *restrict fp);
  • size: 읽을 타입의 크기(바이트)
  • nmemb: 저장/읽을 데이터의 수
  • 반환값은 기록한/읽은 항목의 수를 return
  • 일반적으로 return값 == nmemb 값 (에러 발생 시 다를 수 있음)
profile
올해는 진짜 갓생 산다

0개의 댓글