반응형

문자열은 연속된 문자의 집합이며, 기본 자료형은 char이다.

아두이노에서 문자열의 표현 방법은 배열의 요소로서 문자(자료형 char)를 포함한 배열 형태와 String 자료형을 이용한 문자열(또는 텍스트)을 직접 대입하는 방법이 있다. 

 

배열을 이용한 문자열의 표현

배열을 이용하여 문자열을 표현하는데 있어서 중요한 규칙이 한가지 있게 되는데 "문자열에는 문자열의 종료를 알리는 특수 문자 Nul이 항상 마지막에 위치한다."라는 것이다. 

* 아스키 코드 십진수 0 = 16진수 0x00 = 이진수 0b00000000 = Nul(null, 널 문자) = '\0'

널 문자는 문자열 관련 함수가 문자열의 끝이 어디인지 알 수 있게 하는데 배열에 문자(자료형 char)가 들어있을 때 문자열과 관련된 함수들에 사용되면 관련 함수는 자동으로 배열 인덱스 0부터 널 문자 '\0'를 만날때 까지 읽는다. 즉 이 널 문자에의해 별도의 코딩없이도 문자의 집합인 열을 한번에 출력할 수 있게 되는 것이다. 만약 널 문자가 없는 문자 배열을 문자열 관련 함수에 사용하게 되면 배열의 범위를 넘어서 널 문자를 만날때 까지 문자열의 부분이 아닌 후속 바이트를 계속해서 읽게 된다. 다행이 얼마지나지 않아 널문자를 만나면 그때까지의 문자 또는 바이트 값들을 출력하고 끝나겠지만 만나지 못한다면 오류를 발생할 것이다. 이렇게 널 문자가 추가 됨으로써 만약 문자열("Hello")의 문자의 수가 5개라면 배열의 크기는 6이 되어야 한다.

 

Serial.print() 함수로 작동 방식을 살펴보자.

이 함수는 자료형에 따라(char인지 아닌지) 따라 사용방법을 구분한다.

자료형이 char인 배열인 경우에는 Serial.print(배열 이름)을 사용하고 자동으로 배열 인덱스 0부터 '\0'를 만날때 까지 읽고 출력한다.

자료형이 char가 아닌 경우에는 Serial.print(배열 이름)을 사용할 수 없고 Serial.print(배열 이름[배열 인덱스])형식으로 배열의 요소에 직접 접근하여 사용해야 한다. 따라서 자동으로 배열을 읽지 않으므로 '\0'는 없어도 무방하다.

 

아두이노에서 배열을 이용한 문자열의 표현 방법

문자열은 큰 따옴표("Abc")로 정의되고 이렇게 정의된 문자열에는 널 문자('\0')가 자동으로 포함된다.

* 문자는 작은따옴표('A')안에 정의된다.

char str0[6] = {'H', 'e','l','l','o','\0'};  // 널 문자('\0') 포함한 6바이트 크기의 배열을 정의하면 문자열이 된다.
char str1[] = {'H', 'e','l','l','o','\0'};    // 배열의 크기를 입력되는 값으로 결정
char str2[6] = {'H', 'e','l','l','o'};     // 배열의 빈공간은 널문자('\0')로 채워져 있다. 널문자를 써준것과 같다.
char str3[5] = {'H', 'e','l','l','o'};     // 배열의 크기가 5이고 널문자('\0')가 없다. 문자열 관련 함수에서 오류 발생
char str4[] = "Hello";    // 배열의 크기를 입력되는 값으로 결정, 배열 크기는 '\0'문자를 포함하여 6바이트이다.  
char str5[6] = "Hello";  // 배열의 크기 지정, 배열 크기는 '\0'문자를 포함하여 6바이트이다. 
char str6[5] = "Hello";  // 배열의 크기 지정, '\0'문자를 포함하지 않았다. 문자열 관련 함수에서 오류 발생
char * str7 = "Hello";  // 배열의 크기를 입력되는 값으로 결정하는 배열변수의 주소값으로 접근하고 정의한다. 
String str8 = "Hello";  // 자료형 String을 사용하여 문자열 변수를 선언해 주었다. - String class
String str = "";               // 널 문자('\0')만 들어있는 크기가 1바이트인 빈문자열이다. 

* 자료형 String은 char *와 같음을 알수있다.


긴 문자열 줄 바꾸기 : 긴 스트링을 아래와 같이 wrap(포장 또는 묶음) 할 수 있다:
char myString[] = "This is the first line" 
                            " this is the second line" 
                            " etcetera";

 

문자열로 이루어진 배열

 

 

LCD디스플레이를 가진 프로젝트에서, 스트링의 배열을 설정하는 것이 편할 때가 종종 있다. 스트링 자체가 배열이므로, 이것은 사실상 2차원 배열의 예이다.

char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3", 
                                        "This is string 4", "This is string 5", "This is string 6" 
                                }; 
String myStrings1[] = {"This is string 1", "This is string 2", "This is string 3",  
                                            "This is string 4", "This is string 5", "This is string 6"  
                                   };

 

string.ino
0.00MB

char str0[6] = {'H', 'e','l','l','o','\0'}; // 널 문자('\0') 포함한 6바이트 크기의 배열을 정의하면 문자열이 된다.
char str1[] = {'H', 'e','l','l','o','\0'};   // 배열의 크기를 입력되는 값으로 결정
char str2[6] = {'H', 'e','l','l','o'};       // 배열의 빈공간은 널문자('\0')로 채워져 있다. 널문자를 써준것과 같다.
char str3[5] = {'H', 'e','l','l','o'};       // 배열의 크기가 5이고 널문자('\0')가 없다. 문자열 관련 함수에서 오류 발생
char str4[] = "Hello";  // 배열의 크기를 입력되는 값으로 결정, 배열 크기는 '\0'문자를 포함하여 6바이트이다.  
char str5[6] = "Hello"; // 배열의 크기 지정, 배열 크기는 '\0'문자를 포함하여 6바이트이다. 
char str6[5] = "Hello"; // 배열의 크기 지정, '\0'문자를 포함하지 않았다. 문자열 관련 함수에서 오류 발생
char * str7 = "Hello";  // 배열의 크기를 입력되는 값으로 결정하는 배열변수의 주소값으로 접근하고 정의한다. 
String str8 = "Hello";  // 자료형 String을 사용하여 문자열 변수를 선언해 주었다. - String class
char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3", 
                     "This is string 4", "This is string 5", "This is string 6" 
                    }; 
String myStrings1[] = {"This is string 1", "This is string 2", "This is string 3", 
                     "This is string 4", "This is string 5", "This is string 6" 
                    };

void setup() {
  Serial.begin(9600);
  Serial.println(str0);
  Serial.println(str1);
  Serial.println(str2);
  Serial.println(str3);
  Serial.println(str4);
  Serial.println(str5);
  Serial.println(str6);
  Serial.println(str7);
  Serial.println(str8);
  for (int i = 0; i < 6; i++) { 
    Serial.println(myStrings[i]); 
    delay(500); 
  }
  for (int i = 0; i < 6; i++) { 
    Serial.println(myStrings1[i]); 
    delay(500); 
  }
}

void loop() {
}

 

자료형 String과 String() 함수

String() 함수에 허용되는 자료형: string, char, byte, int, long, unsigned int, unsigned long, float, double

String(val)

String(val, 진법) // 진법: 이진수, 팔진수, 십진수, 16진수

String(val, 소수 자리수) // val의 자료형이 float 또는 double 일때 

 

String stringOne = "Hello String";                               // 문자열을 String 변수에 대입 
String stringOne = String('a');                                       // 문자를 문자열로 변환 -> '\0'추가 
String stringTwo = String("This is a string");           // 문자열을 String 변수에 대입 
String stringOne = String(stringTwo + " with more");    // 두 문자열 결합 
String stringOne = String(13);                                      // 십진수 13을 문자열("13")로 변환.  
String stringOne = String(13, HEX);    // 십진수 13을 헥사값 문자열("d")로 변환 -> ASCII 코드표에는"0D"로 표시됨 

String stringOne = String(45, HEX);    // 십진수 45를 헥사값 문자열("2d")로 변환
String stringOne = String(13, BIN);     // 십진수 13을 이진수 문자열("1101")로 변환 -> 앞쪽의 0은 생략됨 

String stringOne = String(analogRead(0), DEC);   // 자료형 int의 값을 십진수 문자열로 변환 
String stringOne = String(255, BIN);                          // 십진수 13을 이진수 문자열("1111 1111")로 변환 
String stringOne = String(millis(), DEC);                  // 자료형 long의 값을 십진수 문자열로 변환 
String stringOne = String(5.698, 3);                           // 소수를 정해진 자릿수까지 십진수 문자열로 변환

 

String class에 관련해서는 아래 글을 참조하기 바란다.

[arduino] - 아두이노 - 시리얼통신 주요함수와 예제, String class

 

string_example.ino
0.00MB

void setup() {
  Serial.begin(9600);
  String stringOne = "Hello String";             // 고정된 값(상수) 문자열을 문자 오브젝트에 대입
  Serial.println(stringOne);
  stringOne = String('a');                       // 문자를 문자열로 변환 -> '\0'추가
  Serial.println(stringOne);
  String stringTwo = String("This is a string"); // 상수 문자열을 문자열 오브젝트로 변환
  Serial.println(stringTwo);
  stringOne = String(stringTwo + " with more");  // 두 문자열 결합
  Serial.println(stringOne);
  stringOne = String(13);                        // 십진수 13을 문자열("13")로 변환. 
  Serial.println(stringOne);
  stringOne = String(13, HEX);                   // 십진수 13을 헥사값 문자열("d")로 변환 -> ASCII 코드표에는"0D"로 표시됨
  Serial.println(stringOne);
  stringOne = String(45, HEX);                   // 십진수 45를 헥사값 문자열("2d")로 변환
  Serial.println(stringOne);
  stringOne = String(13, BIN);                   // 십진수 13을 이진수 문자열("1101")로 변환 -> 앞쪽의 0은 생략됨
  Serial.println(stringOne);
  stringOne = String(analogRead(0), DEC);        // 자료형 int의 값을 십진수 문자열로 변환
  Serial.println(stringOne);
  stringOne = String(255, BIN);                  // 십진수 13을 이진수 문자열("1111 1111")로 변환
  Serial.println(stringOne);
  stringOne = String(millis(), DEC);             // 자료형 long의 값을 십진수 문자열로 변환
  Serial.println(stringOne);
  stringOne = String(5.698, 3);                  // 소수를 정해진 자릿수까지 십진수 문자열로 변환
  Serial.println(stringOne);
}

void loop() {
}

 

관련 글

[arduino] - 아두이노 - 메모리(SRAM) 공간 확보를 위한 PROGMEM과 F() 매크로의 사용

[arduino] - 아두이노 - 와이파이 모듈 ESP01, WiFiEsp.h 라이브러리 이용 웹페이지에서 디지털핀 원격제어

[arduino] - 아두이노 - 와이파이 매니저, ESP01 soft AP를 통해 공유기 연결용 아이디와 비밀번호 설정하기

 

 

참고 글

https://www.arduino.cc/reference/ko/language/variables/data-types/string/

https://www.arduino.cc/reference/ko/language/variables/data-types/stringobject/

 

 

 

 

+ Recent posts