💭

【C 言語】複数行の文字列リテラル

2024/10/18に公開

依然は文字列の連結関数を使っていたが、実は関数を使わなくてすむことを最近になって知った

test.c
#include <stdio.h>
#include <stdint.h>

int main(void) {
    uint8_t *msg =
      "あいうえお"
      "かきくけこ"
      "さしすせそ";

    printf("%s\r\n", msg);
}

より長いデータの例として HTTP/2 フレームを使ってみる

test.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>

size_t get_size(uint8_t *msg);
void print_hex(uint8_t *msg, size_t size);

uint8_t *pri(void);
uint8_t *settings(void);
uint8_t *ack(void);
uint8_t *headers(void);

int main(void) {
    uint8_t *p = pri();
    print_hex(p, strlen(p));

    uint8_t *s = settings();
    print_hex(s, get_size(s));

    uint8_t *a = ack();
    print_hex(a, get_size(a));

    uint8_t *h = headers();
    print_hex(h, get_size(h));
}

size_t get_size(uint8_t *msg) {
  return (msg[0] << 16) | (msg[1] << 8) | msg[2] + 9;
}

void print_hex(uint8_t *msg, size_t size) {
  for (size_t i = 0; i < size; i += 1) {
    printf(msg[i] > 0xf ? "%2X" : "0%X", msg[i]);
  }
  printf("\r\n");
}

uint8_t *pri(void) {
  return "PRI * HTTP/2.0\x0D\x0A\x0D\x0ASM\x0D\x0A\x0D\x0A";
}


uint8_t *settings(void) {
  return
      "\x00\x00\x0C"
      "\x04"
      "\x00"
      "\x00\x00\x00\x00"
      "\x00\x02\x00\x00\x00\x00"
      "\x00\x03\x00\x00\x00\x64";
}

uint8_t *ack(void) {
  return
    "\x00\x00\x00"
    "\x04"
    "\x01"
    "\x00\x00\x00\x00";
}

uint8_t *headers(void) {
  return
      "\x00\x00\x3a"
      "\x01"
      "\x05"
      "\x00\x00\x00\x01"
      "\x00"
      // 7:method
      "\x07\x3a\x6d\x65\x74\x68\x6f\x64"
      // 3GET
      "\x03\x47\x45\x54"
      "\x00"
      // 5:path
      "\x05\x3a\x70\x61\x74\x68"
      // 1/
      "\x01\x2f"
      "\x00"
      // 7:scheme
      "\x07\x3a\x73\x63\x68\x65\x6d\x65"
      // 4http
      "\x04\x68\x74\x74\x70"
      "\x00"
      // 10:authority
      "\x0a\x3a\x61\x75\x74\x68\x6f\x72\x69\x74\x79"
      // 9localhost
      "\x09\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74";
}

追記。HTTP/2 フレームのデータをヘッダーに分離

test.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "h2frames.h"
// https://gist.github.com/masakielastic/1bdfbb60589b634a2f4e8220da3f35c3

size_t get_size(uint8_t *msg);
void print_hex(uint8_t *msg, size_t size);

int main(void) {
    uint8_t *frames = h2frames();
    size_t frames_size = h2frames_size();
    print_hex(frames, frames_size);
}

size_t get_size(uint8_t *msg) {
  return (msg[0] << 16) | (msg[1] << 8) | msg[2] + 9;
}

void print_hex(uint8_t *msg, size_t size) {
  for (size_t i = 0; i < size; i += 1) {
    printf(msg[i] > 0xf ? "%2X" : "0%X", msg[i]);
  }
  printf("\r\n");
}

Discussion