プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

C言語文字列処理n本ノック

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で取得すると\0null文字が含まれているとき、意図通りにならない可能性があるので注意が必要です。

  // #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);
}