「C++の基礎 - 変数」の版間の差分
(ページの作成:「== 概要 == <br><br> == 数値の桁数 == ==== std::to_string関数およびstd::string::sizeメソッドの使用 ==== 数値の桁数を数える最も簡単な方…」) |
|||
105行目: | 105行目: | ||
number of digits in 1234567 = 7 | number of digits in 1234567 = 7 | ||
number of digits in -1234567 = 7 | number of digits in -1234567 = 7 | ||
<br><br> | |||
== 文字列から整数を解析する == | |||
==== std::stoi関数の使用 ==== | |||
<code>std::stoi</code>関数は、stringヘッダファイルで定義されている文字列ライブラリであり、文字列の値を異なる数値型に変換することができる。<br> | |||
<br> | |||
符号付き整数型の変換には、<code>std::stoi</code>、<code>std::stol</code>、<code>std::stoll</code>が存在する。<br> | |||
<code>std::stoi</code>関数は単一の<code>std::string</code>オブジェクトを引数とするが、整数を格納するアドレスと入力文字列を処理する進数を指定することもできる。<br> | |||
<br> | |||
以下の例では、<code>std::stoi</code>関数の複数のユースケースを示している。<br> | |||
なお、<code>std::stoi</code>関数は文字列中の先頭の空白文字を使用することができるが、それ以外の文字を使用する場合は例外<code>std::invalid_argument</code>がスローされる。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <iostream> | |||
#include <string> | |||
#include <charconv> | |||
using std::stoi; | |||
int main() | |||
{ | |||
std::string s1 = "333"; | |||
std::string s2 = "-333"; | |||
std::string s3 = "333xio"; | |||
std::string s4 = "01011101"; | |||
std::string s5 = " 333"; | |||
std::string s6 = "0x33"; | |||
int num1, num2, num3, num4, num5, num6; | |||
num1 = std::stoi(s1); | |||
num2 = std::stoi(s2); | |||
num3 = std::stoi(s3); | |||
num4 = std::stoi(s4, nullptr, 2); | |||
num5 = std::stoi(s5); | |||
num6 = std::stoi(s6, nullptr, 16); | |||
std::cout << "num1: " << num1 << " | num2: " << num2 << std::endl; | |||
std::cout << "num3: " << num3 << " | num4: " << num4 << std::endl; | |||
std::cout << "num5: " << num5 << " | num6: " << num6 << std::endl; | |||
return EXIT_SUCCESS; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
// 出力例 | |||
num1: 333 | num2: -333 | |||
num3: 333 | num4: 93 | |||
num5: 333 | num6: 51 | |||
<br> | |||
==== std::from_charsの使用 ==== | |||
<code>std::from_chars</code>関数は、int型の整数を解析することができる。<br> | |||
これは、C++17から標準ライブラリに含まれており、<code>charconv</code>ヘッダファイルで定義されている。<br> | |||
<br> | |||
<code>std::stoi</code>関数とは異なり、<code>std::from_chars</code>関数はオブジェクトの長さや境界線を意識せずに文字列の範囲を操作する。<br> | |||
したがって、第1引数と第2引数に範囲の開始と終了を指定、第3引数は変換された値を代入するためのint型の変数を指定する。<br> | |||
<br> | |||
ただし、<code>std::from_chars</code>関数は入力文字列の先頭の<code>-</code>記号しか扱えないため、<br> | |||
以下の例では、変数num5と変数num6では不正な値を出力している。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <iostream> | |||
#include <string> | |||
#include <charconv> | |||
using std::from_chars; | |||
int main() | |||
{ | |||
std::string s1 = "333"; | |||
std::string s2 = "-333"; | |||
std::string s3 = "333xio"; | |||
std::string s4 = "01011101"; | |||
std::string s5 = " 333"; | |||
std::string s6 = "0x33"; | |||
int num1, num2, num3, num4, num5, num6; | |||
std::from_chars(s1.c_str(), s1.c_str() + s1.length(), num1); | |||
std::from_chars(s2.c_str(), s2.c_str() + s2.length(), num2); | |||
std::from_chars(s3.c_str(), s3.c_str() + s3.length(), num3); | |||
std::from_chars(s4.c_str(), s4.c_str() + s4.length(), num4, 2); | |||
std::from_chars(s5.c_str(), s5.c_str() + s5.length(), num5); | |||
std::from_chars(s6.c_str(), s6.c_str() + s6.length(), num6); | |||
std::cout << "num1: " << num1 << " | num2: " << num2 << std::endl; | |||
std::cout << "num3: " << num3 << " | num4: " << num4 << std::endl; | |||
std::cout << "num5: " << num5 << " | num6: " << num6 << std::endl; | |||
return EXIT_SUCCESS; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
// 出力例 | |||
num1: 333 | num2: -333 | |||
num3: 333 | num4: 93 | |||
num5: -1858679306 | num6: 0 | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C++]] | [[カテゴリ:C++]] |
2021年11月14日 (日) 10:19時点における最新版
概要
数値の桁数
std::to_string関数およびstd::string::sizeメソッドの使用
数値の桁数を数える最も簡単な方法は、数値をstd::string
オブジェクトに変換した後、std::string
のsize
メソッドを呼び出して桁数を取得することである。
以下の例では、整数を文字列に変換した後、文字列のサイズを整数として取得している。
ただし、符号記号もカウントするため、負の整数に対して誤った数値が出力されるため、負の整数には使用できない。
#include <iostream>
#include <vector>
#include <string>
template<typename T>
size_t countDigits(T n)
{
std::string tmp = std::to_string(n);
return tmp.size();
}
int main()
{
int num1 = 1234567;
int num2 = -1234567;
std::cout << "number of digits in " << num1 << " = " << countDigits(num1) << std::endl;
std::cout << "number of digits in " << num2 << " = " << countDigits(num2) << std::endl;
exit(EXIT_SUCCESS);
}
// 出力例 number of digits in 1234567 = 7 number of digits in -1234567 = 8
以下の例では、上記の処理に加えて、負の整数の場合は文字列のサイズを1減算している。
#include <iostream>
#include <vector>
#include <string>
template<typename T>
size_t countDigits(T n)
{
std::string tmp = std::to_string(n);
if (n < 0)
{
return tmp.size() - 1;
}
return tmp.size();
}
int main()
{
int num1 = 1234567;
int num2 = -1234567;
std::cout << "number of digits in " << num1 << " = " << countDigits(num1) << std::endl;
std::cout << "number of digits in " << num2 << " = " << countDigits(num2) << std::endl;
exit(EXIT_SUCCESS);
}
// 出力例 number of digits in 1234567 = 7 number of digits in -1234567 = 7
std::string::eraseメソッドおよびstd::remove_if関数の使用
std::string::erase
メソッドおよびstd::remove_if
関数を使用して、数字以外の記号を削除することができる。
ただし、以下の例では、浮動小数点が処理できないことに注意する。
#include <iostream>
#include <vector>
#include <string>
template<typename T>
size_t countDigits(T n)
{
std::string tmp = std::to_string(n);
tmp.erase(std::remove_if(tmp.begin(), tmp.end(), ispunct), tmp.end());
return tmp.size();
}
int main()
{
int num1 = 1234567;
int num2 = -1234567;
std::cout << "number of digits in " << num1 << " = " << countDigits(num1) << std::endl;
std::cout << "number of digits in " << num2 << " = " << countDigits(num2) << std::endl;
exit(EXIT_SUCCESS);
}
// 出力例 number of digits in 1234567 = 7 number of digits in -1234567 = 7
文字列から整数を解析する
std::stoi関数の使用
std::stoi
関数は、stringヘッダファイルで定義されている文字列ライブラリであり、文字列の値を異なる数値型に変換することができる。
符号付き整数型の変換には、std::stoi
、std::stol
、std::stoll
が存在する。
std::stoi
関数は単一のstd::string
オブジェクトを引数とするが、整数を格納するアドレスと入力文字列を処理する進数を指定することもできる。
以下の例では、std::stoi
関数の複数のユースケースを示している。
なお、std::stoi
関数は文字列中の先頭の空白文字を使用することができるが、それ以外の文字を使用する場合は例外std::invalid_argument
がスローされる。
#include <iostream>
#include <string>
#include <charconv>
using std::stoi;
int main()
{
std::string s1 = "333";
std::string s2 = "-333";
std::string s3 = "333xio";
std::string s4 = "01011101";
std::string s5 = " 333";
std::string s6 = "0x33";
int num1, num2, num3, num4, num5, num6;
num1 = std::stoi(s1);
num2 = std::stoi(s2);
num3 = std::stoi(s3);
num4 = std::stoi(s4, nullptr, 2);
num5 = std::stoi(s5);
num6 = std::stoi(s6, nullptr, 16);
std::cout << "num1: " << num1 << " | num2: " << num2 << std::endl;
std::cout << "num3: " << num3 << " | num4: " << num4 << std::endl;
std::cout << "num5: " << num5 << " | num6: " << num6 << std::endl;
return EXIT_SUCCESS;
}
// 出力例 num1: 333 | num2: -333 num3: 333 | num4: 93 num5: 333 | num6: 51
std::from_charsの使用
std::from_chars
関数は、int型の整数を解析することができる。
これは、C++17から標準ライブラリに含まれており、charconv
ヘッダファイルで定義されている。
std::stoi
関数とは異なり、std::from_chars
関数はオブジェクトの長さや境界線を意識せずに文字列の範囲を操作する。
したがって、第1引数と第2引数に範囲の開始と終了を指定、第3引数は変換された値を代入するためのint型の変数を指定する。
ただし、std::from_chars
関数は入力文字列の先頭の-
記号しか扱えないため、
以下の例では、変数num5と変数num6では不正な値を出力している。
#include <iostream>
#include <string>
#include <charconv>
using std::from_chars;
int main()
{
std::string s1 = "333";
std::string s2 = "-333";
std::string s3 = "333xio";
std::string s4 = "01011101";
std::string s5 = " 333";
std::string s6 = "0x33";
int num1, num2, num3, num4, num5, num6;
std::from_chars(s1.c_str(), s1.c_str() + s1.length(), num1);
std::from_chars(s2.c_str(), s2.c_str() + s2.length(), num2);
std::from_chars(s3.c_str(), s3.c_str() + s3.length(), num3);
std::from_chars(s4.c_str(), s4.c_str() + s4.length(), num4, 2);
std::from_chars(s5.c_str(), s5.c_str() + s5.length(), num5);
std::from_chars(s6.c_str(), s6.c_str() + s6.length(), num6);
std::cout << "num1: " << num1 << " | num2: " << num2 << std::endl;
std::cout << "num3: " << num3 << " | num4: " << num4 << std::endl;
std::cout << "num5: " << num5 << " | num6: " << num6 << std::endl;
return EXIT_SUCCESS;
}
// 出力例 num1: 333 | num2: -333 num3: 333 | num4: 93 num5: -1858679306 | num6: 0