大昔とは全然違う言語になっているC++の例です。久しぶりに触ったらもー全て新鮮。
意外な所が楽だったり、面倒だったりします。
/*
* VS2022のcl.exeでコンパイルする場合は、例外処理に関するオプションを付けて
* cl.exe /EHsc basic.cpp
* とします。
* 2023/08/20
*/
#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <regex>
#include <ctime>
using namespace std;
/*============================*
* 複数行のコメントは
* このように
* 書けます。
*============================*/
// 1行コメントはこのように書けます。
// C++にはsplit関数がないので自作が必要
vector<string> split(string s, char sep){
int first = 0;
int last = s.find(sep);
vector<string> result;
// strlen(s)以外にs.size()という書き方もある
while(first < s.size()){
// C++では↓のように他の文字列の部分文字列を切り出しながら変数を初期化できる
// なんでこういう意外な所が便利なのにsplit関数がないのかっていう
string subStr(s, first, last-first);
result.push_back(subStr);
first = last + 1;
// findは文字列を、find_first_ofは文字を検索する関数。今回の目的ならどちらも使える
//last = s.find(sep, first);
last = s.find_first_of(sep, first);
// find等の関数は見つからないとnposという定数を返す。nposの内部的な値は-1
if(last == string::npos){ last = s.size(); }
}
return result;
}
int main(int argc, char* argv[]){
cout << "Hello, World." << endl;
cout << "こんにちは。" << endl;
auto var1 = 42;
auto var2 = 35;
auto var3 = var1 + var2;
auto var4 = var1 - var2;
// どちらも同じ出力
printf("結果は%dと%d\n", var3, var4);
cout << "結果は" << var3 << "と" << var4 << endl;
var2 += 18;
var3--;
var4++;
printf("%d %d %d\n", var2, var3, var4);
// C++の固定長配列には単なる配列(int[]とか)とarrayがある。
// 可変長配列にlistやvectorがある
// ↓array要素の初期化時に "=" は要らないので注意
array<int, 4> arr { var1, var2, var3, var4 };
for(int v : arr){
if(v >= 50){
printf("%dは50以上です。\n", v);
} else if(v >= 40 && v < 50){
printf("%dは40以上50未満です。\n", v);
} else {
printf("%dは50未満です。\n", v);
}
}
double var5 = 1;
for(int i=0; i<arr.size(); i++){
var5 *= arr[i];
}
printf("計算結果:[%-15.2f]\n", var5); // カンマ区切りはできない?
auto str1 = "Hello,Power,Shell,World";
// %zはsize_tに対応するもの。strlenがsize_tを返すため
printf("文字列の長さは%zd\n", strlen(str1));
// 大文字に変換
// C++の標準では文字単位で変換するtoupperしかない
// 文字列全体を変換するにはUnicodeライブラリ等の使用が必要
int len1 = strlen(str1);
for(int i=0; i<len1; i++){
cout << (char)toupper(str1[i]);
}
cout<<endl;
// 配列の分割
vector<string> arr2 = split(str1, ',');
// 配列を表示
for(string v : arr2){
cout << v << " ";
}
cout<<endl;
// Rを付けるとエスケープが不要になる。二重引用符や改行文字もエスケープ不要になり見やすい。
// 頭にRを付けるだけでは駄目で、二重引用符の中に括弧でくくった部分が必須。
// 括弧内の部分がエスケープ不要になる。
// ※RはRaw string literal(生文字列リテラル)の意でありRegular expressionのRとは関係ない
// ※逆に言うと全体を囲む()は正規表現と関係がないので、部分文字列としては検出されない
regex re(R"(^.[opqr])"); // 2文字目がopqrのいずれか
for(string v : arr2){
if(regex_search(v, re)){
cout << v << "はマッチします。" << endl;
} else {
cout << v << "はマッチしません。" << endl;
}
}
// 現在時刻の取得
time_t t1 = time(nullptr);
char dstr1[128];
strftime(dstr1, sizeof(dstr1), "%Y/%m/%d %X", localtime(&t1));
// 指定した年月日の値を取得。順番は秒分時日月年。月は-1、年は-1900する必要がある
struct tm tmtm2 = {0, 0, 0, 26, 4-1, 2020-1900};
time_t t2 = mktime(&tmtm2);
char dstr2[128];
strftime(dstr2, sizeof(dstr2), "%Y/%m/%d %X", localtime(&t2));
// ヒアドキュメントも先のR...で記述できるが、変数を展開できない。
// そのためここではつないでcoutに出す方法にしています。
cout << "現在時刻は" << dstr1 << "です。" << endl <<
"特定の日付とは…" << dstr2 << "です。" << endl;
return 0;
}