2017年10月06日
《その69》 数字文字の並びを数値に変換(p.315演習8-18,演習8-19)
数字文字の並びを数値に変換
(例1) 文字列 "108" を数値に変換
数字文字は、文字コードの差を利用して数値に変換できます。
(本ブログの《その58》をご参照ください。)
'1' は '1' - '0' の計算結果から数値の 1 に
'0' は '0' - '0' の計算結果から数値の 0 に
'8' は '8' - '0' の計算結果から数値の 8 に、それぞれ変換できます。
得られた 1, 0, 8 から
((1 * 10) + 0) * 10 + 8 として 数値 108 が得られます。
(例2) 文字列 "-108" を数値に変換
文字列先頭の '-' は数値 -1 に変換します。
"108" の部分は(例1)と同じようにして 数値 108 に変換します。
得られた -1, 108 から
-1 * 108 として 数値 -108 が得られます。
新版明解C++入門編 p.315 演習8-18
文字列として表された整数値を、int型の整数値に変換した値を返す関数 str2int を作成せよ。
int str2int(const char* s);たとえば、文字列 s が "138" であれば、返却するのは整数値 138 である。s が整数として解釈できないような文字列である場合は、0 を返すこと。
// p315_演習8-18
#include <iomanip>
#include <iostream>
using namespace std;
int str2int(const char* s)
{
const char* p = s;
int num = 0; // num … 求める int型の整数値
int sign = 1; // 正 : sign = 1, 負 : sign = -1, 0 : sign = 0
int n = 0; while (*s++) n++; // n … 文字列の長さ
if (p[0] == '-') /* 最初の文字が '-' */
sign = -1;
else if (p[0] == '+') /* 最初の文字が '+' */
;
else if (p[0] >= '0' && p[0] <='9') /* 最初の文字が '0' 〜 '9' */
num = p[0] - '0';
else { /* 最初の文字が その他 */
sign = 0; goto RETURN;
}
for (int i = 1; i < n; i++) {
if (p[i] >= '0' && p[i] <='9')
num = num * 10 + p[i] - '0';
else {
sign = 0; break;
}
}
RETURN: return sign * num;
}
void disp(char c[])
{
cout << "\"" << c << "\"\t" << " → " << str2int(c) << '\n';
}
int main()
{
char* a01 = "108" ; disp(a01);
char* a02 = "+123" ; disp(a02);
char* a03 = "-120" ; disp(a03);
char* a04 = "++12" ; disp(a04);
char* a05 = "--12" ; disp(a05);
char* a06 = "0005" ; disp(a06);
char* a07 = "-0005"; disp(a07);
char* a08 = "5-3" ; disp(a08);
char* a09 = "6+2" ; disp(a09);
char* a10 = "abc" ; disp(a10);
char* a11 = "z123" ; disp(a11);
char* a12 = "0" ; disp(a12);
char* a13 = "000" ; disp(a13);
char* a14 = "10000"; disp(a14);
}
新版明解C++入門編 p.315 演習8-19
文字列として表された実数値を、double型の実数に変換した値を返す関数 str2double を作成せよ。
double str2double(const char* s);たとえば、文字列 s が "13.5" であれば、返却するのは実数値 13.5 である。s が実数として解釈できないような文字列である場合は、0.0 を返すこと。
// p315_演習8-19
#include <iomanip>
#include <iostream>
using namespace std;
double str2double(const char* s)
{
const char* p = s;
double num = 0.0;
int sign = 1; // 正 : sign = 1, 負 : sign = -1, 0 : sign = 0
int point = 0; // 文字列に含まれる小数点の個数
double scale = 1.0; // 最後に scale倍して位取り調整
int n = 0; while (*s++) n++; // n … 文字列の長さ
if (p[0] == '-') /* 最初の文字が '-' */
sign = -1;
else if (p[0] == '+') /* 最初の文字が '+' */
;
else if (p[0] == '.') /* 最初の文字が '.' */
point++;
else if (p[0] >= '0' && p[0] <= '9') /* 最初の文字が '0' 〜 '9' */
num = p[0] - '0';
else { /* 最初の文字が その他 */
sign = 0; goto RETURN;
}
for (int i = 1; i < n; i++) {
if (p[i] >= '0' && p[i] <= '9') {
num = num * 10.0 + p[i] - '0';
if (point == 1)
scale = scale / 10; /* 小数点以降は位取り要調整 */
}
else if (p[i] == '.') {
point++;
if (point > 1) { /* 2個目の小数点を検出 */
sign = 0; break;
}
}
else {
sign = 0; break;
}
}
RETURN: return sign * num * scale;
}
void disp(const char* s)
{
int n = 0; // n … 文字列の長さ
while (s[n])
n++;
double a = str2double(s);
cout << "\"" << s << "\"";
for (int i = 0; i < 8 - n; i++)
cout << ' ';
cout << " → " << str2double(s);
if (a == (int)a) /* aの値が整数のとき */
cout << ".0"; // 「 .0 」を付加
cout << '\n';
}
int main(void)
{
char str01[] = "12.3456" ; disp(str01);
char str02[] = "2.3.4" ; disp(str02);
char str03[] = "2.." ; disp(str03);
char str04[] = "-5" ; disp(str04);
char str05[] = "0" ; disp(str05);
char str06[] = "000000" ; disp(str06);
char str07[] = "12 345" ; disp(str07);
char str08[] = ".012345" ; disp(str08);
char str09[] = "-123.456"; disp(str09);
char str10[] = "+-1.234" ; disp(str10);
char str11[] = "+123456" ; disp(str11);
char str12[] = "a12" ; disp(str12);
char str13[] = "0.0001" ; disp(str13);
char str14[] = "." ; disp(str14);
char str15[] = "0135" ; disp(str15);
char str16[] = "00.000" ; disp(str16);
}
--
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/6781829
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック