UARTおじさんのためのチートシート

C,C#,Java,Swiftで数値⇔文字列⇔バイト列の変換処理のチートシート
マイコンWindowsAndroidiOSのデータのやりとり、ぜんぶシリアル通信でやるんだ。
(自虐ネタ)

C

#include <stdio.h> // sprintf, sscanf
#include <string.h> // memcpy

// (1) 数値→文字列 sprintfを使う
char str[256];
int iVal = 10;
double fVal = 5.5;

sprintf(str, "%d", iVal);
sprintf(str, "%f", fVal);
sprintf(str, "%5d", iVal); // 桁数指定
sprintf(str, "%04X", iVal); // 16進数
sprintf(str, "%5.2f", fVal); // 桁指定(%全桁数.小数点以下桁数であることに注意)

// (2) 文字列→数値 sscanf()を使う
int ret;

ret = sscanf(str, "%d", &iVal);
ret = sscanf(str, "%f", &fVal);
ret = sscanf(str, "%5d", &iVal); // 桁数指定
ret = sscanf(str, "%04X", &iVal); // 16進数
ret = sscanf(str, "%5.2f", &fVal); // 桁指定(%全桁数.小数点以下桁数)

// ret は変換した個数
if(ret!=1){
    // 異常系
}

// (3) 文字列→バイト列
// (4) バイト列→文字列
// C言語ではそもそも文字列はバイト列(char配列)にすぎない

// (5) 文字列の切り出し memcpyを使う
memcpy(substr, &str[3], 2);
substr[2] = '\0';
// が、ポインタ操作だけで済ますことも(上記(2)と関連)
ret = sscanf(&str[3], "%02X", &iVal); // strの4文字目から2文字を変換

C#

using System.Text; // Encoding.ASCII.GetBytes
using System.Globalization; // NumberStyles.HexNumber

// (1) 数値→文字列 ToStringを使う
string str;
int iVal = 10;
double fVal = 5.5;

str = iVal.ToString();
str = fVal.ToString();
str = iVal.ToString("X4"); // 16進数
str = fVal.ToString("F2"); // 桁指定(小数点以下桁数)

// (string.Formatならより複雑な指定ができる)
str = string.Format("{0, 8:D4}", iVal) // → "    0001"


// (2) 文字列→数値 Parseを使う
try{
    iVal = int.Parse(str);
    iVal = int.Parse(str, NumberStyles.HexNumber); // 16進数
    fVal = double.Parse(str);

    // Convertクラスでも同様
    iVal = Convert.ToInt32(str);
    iVal = Convert.ToInt32(str, 16); // 16進数
    fVal = Convert.ToDouble(str);
}
catch (FormatException ex){
    // 異常系
}
catch (OverflowException ex){
    // 異常系
}

// (3) 文字列→バイト列 GetBytesを使う
byte[] data = Encoding.ASCII.GetBytes(str);

// (4) バイト列→文字列 GetStringを使う
string str = Encoding.ASCII.GetString(data);

// (5) 文字列の切り出し Substringを使う
// ※ Javaのsubstringとは2番目の引数の意味が違うことに注意
string sub = str.Substring(4,2); // 5文字目から2文字

Java

// (1) 数値→文字列 valueOfやformatを使う
String str;
int iVal = 10;
double fVal = 5.5;

str = String.valueOf(iVal);
str = String.valueOf(fVal);
str = String.format("%04X",iVal); // C言語と同様の書式指定
str = String.format("%5.2f",fVal); // C言語と同様の書式指定

// (2) 文字列→数値 parseInt,parseDoubleを使う
try{
    iVal = Integer.parseInt(str);
    iVal = Integer.parseInt(str, 16); // 16進数
    fVal = Double.parseDouble(str);
}
catch (NumberFormatException ex) {
    // 異常系
}

// (3) 文字列→バイト列 getBytesを使う
byte[] data = str.getBytes();

// (4) バイト列→文字列 Stringをnewする
String str = new String(data);

// (5) 文字列の切り出し substringを使う
// ※ C#のSubstringとは2番目の引数の意味が違うことに注意
String sub = str.substring(4,6); // 5文字目から2文字

Swift

SwiftはUARTおじさんにはツラい言語。
というかよく分かりません。いちおうメモしておきます。

//1) 数値→文字列 StringやNSStringを生成
let iVal = 10 // Int
let fVal = 5.5 // Double

let str = String(iVal)
let str = String(fVal)
let str = NSString(format:"%04X", iVal) // C言語と同様の書式指定
let str = NSString(format:"%5.2f", fVal) // C言語と同様の書式指定

// (2) 文字列→数値 IntやDoubleを生成
guard let iVal2 = Int(str) else{
    // 異常系
    return;
}

// 異常なら0 のようにしたい場合は ?? を使う
let iVal = Int(str) ?? 0
let iVal = Int(str, radix: 16) ?? 0 // 16進数
let fVal = Double(str) ?? 0

// (3) 文字列→バイト列
if let data: Data = str.data(using: String.Encoding.utf8)
{
    var bytes = [UInt8](repeating: 0, count: data.count)
    data.copyBytes(to: &bytes, count: data.count)
}

// (4) バイト列→文字列
let ns = NSData(bytes: &bytes, length: bytes.count)
let str = NSString(bytes: bytes, length: bytes.count, encoding: String.Encoding.ascii.rawValue)

// (5) 文字列の切り出し substringWithRangeを使う
let sub = str.substring(to: str.characters.index(str.startIndex, offsetBy: 6))

まとめ

数値→文字列 文字列→数値 文字列→バイト列 バイト列→文字列 部分文字列
C sprintf sscanf - - -
C# ToString Parse GetBytes GetString Substring
Java valueOf/format parseInt/parseDouble getBytes new String substring
Swift String/NSString Int/Double data/copyBytes NSData/NSString substring