서식에 맞춰 시리얼 모니터에 출력하기 위하여 sprintf(...) 함수를 종종 사용하는데, 정수(%d), 문자(%c), 문자열(%s), 16 진수 값들(%x 혹은 %X)은 별 문제가 없는데 부동 소수 값(%f)을 출력하면 시리얼 모니터에 "?"만 출력 됩니다.
void setup() {
// 여기에 초기화 부분을 넣어 주세요. 이것은 한번만 실행됩니다.
char buf[32];
float t1 = 29.15;
Serial.begin(9600);
sprintf(buf, "T1 온도: %3.2f℃", t1);
Serial.println(buf);
}
void loop() {
// 여기에 주 처리 부분을 넣어 주세요. 이것은 반복 실행됩니다.
}
1. String(float, [precision]).c_str()
String(float, [precision]).c_str() 함수를 사용하면 쉽게 부동 소수를 문자열로 바꿔 출력할 수 있습니다. precision은 부동 소수점 아래 숫자를 몇 자리까지 출력할 것인지 결정을 위한 값이며 이를 넣지 않으면 기본으로 2 자리 숫자가 출력 됩니다
void setup() {
// 여기에 초기화 부분을 넣어 주세요. 이것은 한번만 실행됩니다.
char buf[32];
float t1 = 29.15;
float t2 = 100.0;
Serial.begin(9600);
sprintf(buf, "T1 온도: %8s℃", String(t1, 1).c_str());
Serial.println(buf);
sprintf(buf, "T2 온도: %8s℃", String(t2, 2).c_str());
Serial.println(buf);
}
void loop() {
// 여기에 주 처리 부분을 넣어 주세요. 이것은 반복 실행됩니다.
}
2. dtostrf(double, width, precision, buffer)
부동 소수 값을 C 문자열로 바꿔 주는 dtostrf(...) 함수를 사용하여도 같은 결과를 얻을 수 있습니다:
void setup() {
// 여기에 초기화 부분을 넣어 주세요. 이것은 한번만 실행됩니다.
char buf[32];
char temp[8];
float t1 = 29.15;
float t2 = 100.0;
Serial.begin(9600);
dtostrf(t1, 3, 1, temp);
sprintf(buf, "T1 온도: %8s℃", temp);
Serial.println(buf);
dtostrf(t2, 3, 2, temp);
sprintf(buf, "T2 온도: %8s℃", temp);
Serial.println(buf);
}
void loop() {
// 여기에 주 처리 부분을 넣어 주세요. 이것은 반복 실행됩니다.
}
결과
sprintf(char *buf, const char *format, ...) 함수에서 format 문자열은 buf에 저장되는 문자열의 서식(형식)을 지정하기 위하여 사용됩니다. format은 %[flags][width][.precision][length]specifier로 이뤄집니다.
아두이노에서 지원되는 서식은 성능과 효율성을 위하여 제한적입니다.
서식(format) 양식
%[flags][width][.precision][length]specifier
flags
- 사용되는 width 안에서 왼쪽 정렬
+ +와 - 기호를 숫자 앞에 강제로 출력
# o, x 혹은 X 서식 지정자(specifier)와 같이 사용. 숫자 앞에 0, 0x, 혹은 0X 등을 붙임
0 숫자 앞에 0을 붙임. 0와 공백 문자는 사용된 width 보다 작을 때 붙여 짐
width
숫자 출력할 정수 혹은 문자열의 최소 폭을 지정.
폭보다 출력 되는 숫자 혹은 문자열이 작을 경우 ' '(공백 문자)가 앞에 붙음.
<- 0 flag이 붙은 숫자는 0가 붙음
.precision
숫자 d, i, o, u, x 혹은 X 서식 지정자와 같이 사용되어
최소 출력 되는 숫자 길이를 지정하며,
작을 경우 앞에 0을 붙임. 숫자 길이가 긴 경우 잘려 출력 되는 경우는 없음.
length (혹은 modifier를 사용)
h i, d 혹은 u 서식 지정자와 같이 사용되어 short 값을 출력할 때 사용
l i, d 혹은 u 서식 지정자와 같이 사용되어 long int 혹은 unsigned long int 값을 출력할 때 사용
specifier
c 글자(char)를 출력 d 부호가 있는 정수 값 출력
i 부호가 있는 정수 값 출력
u 부호가 없는 정수 값 출력
o 8 진수 부호가 없는 정수 값 출력
x 16 진수 부호가 없는 정수 값 출력.
a ~ f 소문자가 출력 됨.
X 16 진수 부호가 없는 정수 값 출력.
A ~ F 대문자가 출력 됨.
p 포인터 값이 16 진수 값으로 출력 되며,
x 지정자를 사용한 것과 같이 소문자로 출력 됨 s 문자열을 출력
스케치
간단하게 여러 format으로 출력하는 예제 스케치를 만들어 시험하여 보았습니다:
/*
* sprintf2
*
* 이 스케치는 sprintf 함수를 이용하여 문자, 숫자들, 포인터, 그리고
* 문자열을 서식(양식)에 맞춰 출력한 예제입니다.
*
* 이 예제 코드는 공유 저작물입니다.
*
*/
#define MAX_TYPE(type) ((type)(pow(2, sizeof(type) * 8 - 1) - 1))
#define MAX_INT MAX_TYPE(int)
#define MAX_LONG MAX_TYPE(long)
void setup() {
// 여기에 초기화 부분을 넣어 주세요. 이것은 한번만 실행됩니다.
char buf[80];
Serial.begin(9600);
Serial.println("sprintf() 예제 2");
Serial.println("================");
sprintf(buf, "문자들: '%c', '%c'", 'a', (char)97); Serial.println(buf);
sprintf(buf, "숫자들: %10i, %li", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "숫자들: %d, %ld", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "숫자들: %d, %ld", (unsigned int)(MAX_INT + 1), (unsigned long)(MAX_LONG + 1)); Serial.println(buf);
sprintf(buf, "숫자들: %u, %lu", (unsigned int)(MAX_INT + 1), (unsigned long)(MAX_LONG + 1)); Serial.println(buf);
sprintf(buf, "' ' 문자를 앞에 넣은 숫자: %10d", MAX_INT); Serial.println(buf);
sprintf(buf, "'0' 문자를 앞에 넣은 숫자: %010d", MAX_INT); Serial.println(buf);
sprintf(buf, "왼쪽 정렬: %-10d %ld", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "오른쪽 정렬: %10d %ld", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "오른쪽 정렬: %10.8d %ld", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "+ 기호: %+10d %+ld", MAX_INT, MAX_LONG); Serial.println(buf);
sprintf(buf, "진수들: %04d %04o %#4o %04x %#4x %04X %#4X", 254, 254, 254, 254, 254, 254, 254); Serial.println(buf);
sprintf(buf, "진수들: %4d %4o %#4o %4x %#4x %4X %#4X", 254, 254, 254, 254, 254, 254, 254); Serial.println(buf);
sprintf(buf, "포인터: %p", &buf); Serial.println(buf);
sprintf(buf, "문자열: %s", "아두이노"); Serial.println(buf);
}
void loop() {
// 여기에 주 처리 부분을 넣어 주세요. 이것은 반복 실행됩니다.
}
실행
스케치를 업로드하고 시리얼 모니터를 열면 다음과 같은 결과를 얻을 수 있습니다: