[C/C++ 프로그래밍 강좌 목차]
안녕하세요 주인장 양햄찌입니다.
오늘은 마치 생긴건 기본적인 printf 랑 비슷하게 생긴,
정말정말 유용하게 많이 쓰이는 printf 친척쯤 되는 sprintf와 fprintf 함수를 들고 왔어요.
printf는 서식지정이 가능한 출력 함수죠?! 얘네들은 printf의 서식표현 방법을 기본적으로 따라가기 때문에 printf를 사용하실 줄 알아야 합니다.
%d, %s, %c, %e, %f 등의 서식연사자들,, 그리고 0, #, + 등의 플래그들..
혹 해당 함수의 다양한 사용법을 다시 확인하고 싶은 방문자들은 아래 포스팅을 참고 바라요.
[C, Java] Hello World 출력, printf 출력 함수 서식과 포맷, 소수점 자리 지정법, 채우기
[ C/ C++ / Java] 프로그래밍 기초 목차편! 안녕하세요~! 프로그래밍 기초편 포스팅을 시작해봅시다 ㅎㅎ 저번시간에 개발할 수 있는 개발환경을 다 설치했으니 간단한 프로그램을 작성해봐야겠죠 �
jhnyang.tistory.com
printf, sprintf, fprintf 함수 헤더
#include <cstdio> //C++
#include <stdio.h> //C
세 함수는 모두 같은 라이브러리에 속해있습니다. stdio.h나 cstdio 라이브러리를 인클루드 시켜주면 사용 가능해요.
해당 헤더에 속하는 printf 비스므리하게 생긴 애들 중 vprintf, vsprintf, vsnprintf 요런 애들도 있는데 요 함수들은 가변인자때 사용되는 출력함수예요. 가변인자 사용법에 대해 공부하고 싶으신 분은 아래 포스팅을 참고해주세요.
sprintf 알아보기
printf는 여러가지 서식들을 조합해서 출력을 해줘요. 영어+숫자+헥사값 등등 포맷연산자에 포맷만 지정해주면 다양한 값을 한 번에 출력을 해주죠! 근데 출력말고, 개발하다보면 이를 변수에다가 저장해서 활용하고 싶을 때가 많습니다.
그렇습니다~~! sprintf는 출력하는 결과 값을 변수에 저장하게 해주는 기능이 있어요. 저는 그래서 'string = printf'의 줄임말이 sprintf이다 라고 생각을 하고 있습니다. printf가 출력하는 함수라면 sprintf는 출력값을 문자열에 저장하는 함수인거죠ㅎㅎ.
해당 함수로 인해 문자열 사이에 특정 값을 끼어넣는다던가,, 문자열+숫자 조합을 쉽게 컨트롤한다던가,,
마스킹처리와 같은 특정 포맷을 만든다던가,, 다양하게 활용할 수 있습니다.
sprintf 프로토타입
int sprintf ( char * str, const char * format, ... );
리턴 값
문자열 변수 str에 쓰기가 성공한 문자 개수가 반환된다.
인자 값
char* str : 출력값을 저장할 문자열.
const char* format : 서식 문자열
... : 서식 연산자에 치환할 값들
(2번째 인자부터는 printf 출력함수 사용 방법과 동일합니다)
sprintf 기본적인 사용 예시
가장 빠르게 익히는 법은 사용예시를 보는 거죠.
#include <stdio.h>
#include <string.h>
int main()
{
char msg1[50] = { 0x00, }, msg2[50] = { 0x00, }, msg3[50] = { 0x00, };
int y = 2020; int m = 8; int d = 30;
sprintf(msg1, "hello"); //msg1에 단순 문자열 저장.
printf("%s\n", msg1);
sprintf(msg2, "%s world!", msg1); //msg2에 "msg1 문자열 내용 + world!"
printf("%s\n", msg2);
sprintf(msg3, "%s%.6s 오늘은 %d%d%d", msg1, msg2 + strlen(msg1), y, m, d); //msg3에 문자열과 숫자 조합해서 저장하기
printf("%s\n", msg3);
return 0;
}
이렇게 내가 넣고 싶은 정보들을 같이 조합하여 문자열로 만들어 저장할 수 있습니다.
리턴 값까지 확인해보기!
#include <stdio.h>
#include <string.h>
int main()
{
char msg1[50] = { 0x00, }, msg2[50] = { 0x00, }, msg3[50] = { 0x00, };
int y = 2020; int m = 8; int d = 30;
int len = sprintf(msg1, "hello"); //msg1에 단순 문자열 저장.
printf("%d %d :%s \n", len, strlen(msg1), msg1);
len = sprintf(msg2, "%s world!", msg1); //msg2에 "msg1 문자열 내용 + world!"
printf("%d %d :%s \n", len, strlen(msg2), msg2);
//msg3에 문자열과 숫자 조합해서 저장하기
len = sprintf(msg3, "%s%.6s 오늘은 %d%d%d", msg1, msg2 + strlen(msg1), y, m, d);
printf("%d %d :%s \n", len, strlen(msg3), msg3);
return 0;
}
strlen함수는 널문자가 나타나기까지 길이를 카운트하죠. sprintf함수로 만든 msg1 문자열의 strlen값이 5라는 것은, sprintf로 문자열을 만들시 마지막에 널문자를 자동적으로 삽입해준다는 의미가 됩니다.
★ sprintf 함수를 이용하여 문자열을 만들시 마지막 널문자도 같이 삽입이 된다!
성공적으로 write한 값과 strlen 값이 동일한 것을 확인할 수 있어요. 이 값은 결국 널문자를 제외한 문자열의 길이를 의미하죠 :)
[예시, 절대경로포함한 파일명 만들기]
#pragma warning(disable:4996)
#include <stdio.h>
#define FILE_PATH "/home/ubuntu/"
int main()
{
const char* fname = "hello.txt";
char file[100] = { 0x00, };
sprintf(file, "%s%s", FILE_PATH, fname); //절대경로를 가진 파일명 만들기
printf("full path: %s", file);
return 0;
}
보통 파일 절대 경로라던가, 날짜를 조합한다던가 이럴 경우 sprintf가 유용하게 쓰여요.
fprintf 알아보기
fprintf 함수는 sprintf 함수와 매~~우 유사한데 출력 값을 쓰는(write하는) 공간이 다른 것 뿐이예요.
sprintf는 문자열에 쓰는 거라면 fprintf는 출력을 파일에다가 쓰는 거죠!
그래서 sprintf 첫번째 인자에 문자열이 왔다면, fprintf 첫번째 인자에는 파일구조체 포인터가 오는거랍니당.
fprintf 프로토타입
int fprintf (FILE* stream, const char* format, ...);
리턴 값
파일에 성공적으로 write한 문자의 개수
인자 값
FILE* stream : write할 파일 정보를 담고 있는 파일객체
const char* format : 서식 문자열
... : 서식 연산자에 치환할 값들
(2번째 인자부터는 printf 출력함수 사용 방법과 동일합니다)
fprintf 기본적인 사용 예시
hello.txt 파일에다가 단순히 hello world! 출력해보기!
#include <stdio.h>
#include <string.h>
int main()
{
FILE* fpw = fopen("hello.txt", "w");
fprintf(fpw, "hello world!");
fclose(fpw);
return 0;
}
단순히 hello.txt 파일을 w쓰기 모드로 연 다음에 해당 파일에다가 hello world!를 출력해줬어요.
짠 수행해보면 잘 쓰여진 것을 확인하실 수 있습니다.
[fprintf는 버퍼에다가 값을 쓴다]
파일입출력 가장 중요한 내용 중 하나는 버퍼죠
1. #include <stdio.h>
2. int main()
3. {
4. FILE* fpw = fopen("hello.txt", "w");
5. FILE* fpr = fopen("hello.txt", "r");
6. char msg[100];
7. fprintf(fpw, "hello world");
8. fgets(msg, 10, fpr);
9. printf("%s", msg);
10. fclose(fpr);
11. fclose(fpw);
12. return 0;
13. }
위 코드를 돌려보면 쓰레기 값이 나오는데요,
왜 이런 값이 나왔을까요??
우리는 7번라인에서 파일에 'hello world'를 쓰고 8번라인에서 fgets함수로 fprintf함수로부터 쓰여진 hello world 문자열에서 10글자를 읽어들일 것이라고 예측하는데요.
사실 7번 라인이 끝났을 때 실질적으로 파일에 쓰여진 것은 아니기 때문에 해당 파일은 빈 파일로 남아있습니다.
따라서 8번 라인에서 빈 파일을 읽으려니까 쓰레기 값이 출력된거예요!
fputs 함수와 마찬가지로 fprintf는 파일에다가 바로 write하는 것이 아니라 버퍼에다가 적습니다. 그리고 fclose함수를 만나면 버퍼에 있던 문자열이 파일에 써지게 돼요. 만약 그 전에 파일에 써서 위와 같은 코드를 정상동작 시키려면 버퍼를 파일에 내보내, 즉 버퍼를 비우는 함수를 사용해야 합니다.
#include <stdio.h>
int main()
{
FILE* fpw = fopen("hello.txt", "w");
FILE* fpr = fopen("hello.txt", "r");
char msg[100];
fprintf(fpw, "hello world");
fflush(fpw); //버퍼 비우기
fgets(msg, 10, fpr);
printf("%s", msg);
fclose(fpr);
fclose(fpw);
return 0;
}
fflush를 통해 버퍼에 있던 값을 파일로 내보내 버퍼를 비워줬어요.
수행해보면 "hello world"에서 10글자에 해당하는 "hello wor"을 잘 출력해준 것을 확인하실 수 있어요.
오늘은 간단하게 sprintf, fprintf 함수에 대해 알아보았어요. ㅎㅎ
도움이 되셨다면 공감 어떠신가요?! 다음에 또 봐요 :)
최신 댓글