C言語 - C/C++ 併用 - 変換

クラウディア 
1. 概要
2. std::string → char*
3. char → std::string
4. 数値 → std::string
5. C++ で printf 書式を使う
6. 16進値

1. 概要

 ややこしいのが、「char*」と「std::string」あたりのそれぞれ独特な型を変換することです。  本ページは、下記のサイトを参考にさせていただきました。
C++ で std::string を char* に変換する」
「[C++11~] 数値を文字列(std::string)に変換する #C++」
「iostream や std::stringでprintf のような書式指定を行う方法 (C++11版) 」
「C++ で数値と文字列の相互変換 #競技プログラミング」
「C++ のコードを何も考えずにclangでコンパイルしたらこけた #clang++」
「【C++】charをstring型に変換する方法(値 配列 ポインタ → 文字列)」
「C++ で整数を 16 進文字列に変換する

2. std::string → char*


#include <iostream>
#include <string>
#include <stdio.h>

int main(int argc, char* argv)
{
	std::string st = "fugafuga";
	printf("%s\n", st);
	return 0;
}
 てな、ソースを書いて、コンパイルすると、エラーになっちゃう。

stringtoc.cpp:5:5: error: second parameter of 'main' (argument array) must be of type 'char **'
    5 | int main(int argc, char* argv)
      |     ^
stringtoc.cpp:8:17: error: cannot pass non-trivial object of type 'std::string' (aka 'basic_string<char>') to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs]
    8 |         printf("%s\n", st);
      |                 ~~     ^~
stringtoc.cpp:8:17: note: did you mean to call the c_str() method?
    8 |         printf("%s\n", st);
      |                        ^
      |                          .c_str()
2 errors generated.
 「c_str()」を使います。

    printf("%s\n", st.c_str());
 と書き換えれば、コンパイルは通るし、出力結果が。

fugafuga
 となります。

3. char* → std::string

 前項の逆パターンですな。  「std::string()」でいけます。  下記のような感じ。

const char *cstr = "abc";
std::string str = std::string(cstr);

4. 数値 → std::string

 数値を「std::string」に変換するには、「std::to_string()」を使うらしく。

#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
    int    i = 10;
    double d = 12.5;
    std::cout << "i = [" << std::to_string(i) << "] d =[" << std::to_string(d) << "]" << std::endl;
    return 0;
}
 てな書き方をするらしいのですが。  「gcc 13.3.0」も「clang 18.1.5」も

    std::cout << "i = [" << i << "] d =[" << d << "]" << std::endl;
 と書いても、エラーにはならず、リンクまで出来ました。  出力結果が異なり、前者は。

i = [10] d =[12.5]
 で、後者は。

i = [10] d =[12.500000]
 となります。

5. C++ で printf 書式を使う

 前項のように、書式が安定しないとき、「C++」で、「C」の「printf」の書式を使いたいなと思ったら。  そういう書き方を説明しているサイトがありました。

#include <string>
#include <cstdio>
#include <vector>

template <typename ... Args>
std::string format(const std::string& fmt, Args ... args )
{
    size_t len = std::snprintf( nullptr, 0, fmt.c_str(), args ... );
    std::vector<char> buf(len + 1);
    std::snprintf(&buf[0], len + 1, fmt.c_str(), args ... );
    return std::string(&buf[0], &buf[0] + len);
}
 という定義を書いておけば。

#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << format("%e", 1./3)  << std::endl;
    return 0;
}
 というソースを実行すると、下記の結果が得られます。

3.333333e-01

6. 16進値

 前項の「printf」型の書式指定ができりゃ、まぁ、これは必要ないのですが。  「std::hex」というものを使用して、数値を16進値で表現できます。  下記のソースを書いて。

#include <iostream>
#include <sstream>

int main(int argc, char* argv[])
{
    int num = 255;

    std::ostringstream ss;
    ss << "0x" << std::hex << num;

    std::cout << ss.str() << std::endl;

    return 0;
}
 コンパイル・リンク後、実行すると下記の結果が得られます。

0xff
earthcar(アースカー)
薬屋の独り言
葬送のフリーレン Prime Video