C言語での文字・文字列の処理をまとめます
私だけでしょうか?文字列の処理がぱっと思い出せないことが度々あるのでここにまとめます。
文字列と数値の変換
// #include <stdlib.h> // 整数から文字列への変換 int number = 42; char str[20]; // 十分なサイズを確保 sprintf(str, "%d", number); printf("str = %s\n", str); // str = 42 // 文字列から整数への変換 char strNumber[] = "42"; number = atoi(strNumber); printf("number = %d\n", number); // number = 42 // 浮動小数点数から文字列への変換 double floatingNumber = 3.14; str[20]; sprintf(str, "%f", floatingNumber); // str = 3.140000 printf("str = %s\n", str); // 文字列から浮動小数点数への変換 char strFloat[] = "3.14"; floatingNumber = atof(strFloat); printf("number = %f\n", floatingNumber); // number = 3.140000
文字列の長さ取得
文字列の長さをstrlen
で取得すると\0
null文字が含まれているとき、意図通りにならない可能性があるので注意が必要です。
// #include <cstring> char a[] = "Hello world"; char b[12] = "Hello world"; char c[] = "Hello\nworld\n"; char d[] = "Hello\0world\0"; int la = strlen(a); // 11 int la2 = sizeof(a) / sizeof(char); // 12 int lb = strlen(b); // 11 int lb2 = sizeof(b) / sizeof(char); // 12 int lc = strlen(c); // 12 int lc2 = sizeof(c) / sizeof(char); // 13 int ld = strlen(d); // 5 null文字があるところまで int ld2 = sizeof(d) / sizeof(char); // 13 }
配列をポインタで関数に渡すときは長さが分からなくなります。一般的には長さが分かっているときは引数を追加して渡します。
#include <stdio.h> size_t calculateLength(const char *str) { size_t length = 0; // ポインタが指す文字列の終端に達するまでループ while (*str != '\0') { length++; str++; } return length; } int main() { char str[] = "Hello World"; int length = calculateLength(str); printf("Length = %d\n", length); //11 return 0; }
文字列をスペース区切りで分割
#include <stdio.h> #include <string.h> void splitString(const char *input, char *output[], size_t *count) { char *token; *count = 0; // 最初のトークンを取得 token = strtok((char *)input, " "); // トークンがNULLでない限りループ while (token != NULL) { output[*count] = token; (*count)++; // 次のトークンを取得 token = strtok(NULL, " "); } } int main() { char input_string[] = "Hello World C Programming"; char *output_array[10]; size_t count; // 関数を呼び出して文字列をスペースで分割 splitString(input_string, output_array, &count); // 結果を出力 printf("strings\n"); for (size_t i = 0; i < count; i++) { printf("%d: %s\n", i + 1, output_array[i]); } return 0; } /* Hello World C Programming */
文字列を16進数として数値に変換
#include <stdio.h> #include <stdlib.h> int main() { char hex_string[] = "f1"; // strtol関数を使用して16進数に変換 long number = strtol(hex_string, NULL, 16); // 結果を出力 printf("HEX = %X\n", number); //HEX = F1 printf("DECIMAL = %d", number); //DECIMAL = 241 return 0; }
文字列を2文字づつに分割して16進数として数値に変換し配列に格納
#include <stdio.h> #include <stdint.h> #include <string.h> int main() { char hex_string[] = "f1020c0d1c1d"; // 16進数の文字列 // 2文字ずつ格納するための配列 uint8_t numbers[6]; // 文字列を2文字ずつ読み取り、数値に変換して配列に格納 for (int i = 0; i < 8; i++) { sscanf(hex_string + i * 2, "%2hhx", &numbers[i]); } // 結果を出力 for (int i = 0; i < 8; i++) { printf("Number %d: %x\n", i + 1, numbers[i]); } return 0; } /* Number 1: f1 Number 2: 2 Number 3: c Number 4: d Number 5: 1c Number 6: 1d Number 7: 66 Number 8: 31 */
文字列を結合する
snprintf
を使うことで文字列を作ることが出来ます。作成される文字列はprintf
で出力するのとほぼ同様にできます。
snprintf
では出力先の配列のサイズを超えた文字列を作ることはできませんし、出力サイズを制御することが出来ます。
また、終端にはnull文字列が付加されます。
#include <stdio.h> int main(void){ char str1[] = "aaaa"; char str2[] = "bbbb"; int num = 1; char buffer[12]; char *p = buffer; snprintf(p, 10, "%s#%d%s", str1, num, str2); printf("buffer = %s\n", buffer); // buffer = aaaa#1bbb snprintf(p, 11, "%s#%d%s", str1, num, str2); printf("buffer = %s\n", buffer); // buffer = aaaa#1bbbb }
memcpyで文字列を作ることもできます。
この場合は、数値を文字に変換する必要があります。
#include <stdio.h> #include <string.h> int main(void) { char str1[] = "aaaa"; char str2[] = "bbbb"; int num = 1; char buffer[12]; char *p = buffer; memcpy(p, str1, 4); p += 4; sprintf(p, "%d", num); p += 1; memcpy(p, str2, 4); printf("buffer = %s\n", buffer); }