FC2ブログ

次の日常:exist, コマンドライン引数, クラスのpublicにルール?, sstream

if(exist(<引数>)){
continue;
}
なんてしてみると英語で読んだとおりにかけるのだなぁと感心.ただ,実装してるときにはわかりづらい.
こういう書き方をするには当然bool exist(<引数>); で定義すればよいですね.まだboolを自分で使うには抵抗があったけど,
使ってみようかな.


int main(int argc, char* argv[]){
なんて始まるのをいつだか学んだんですが,この引数のことをコマンドライン引数と呼ぶのですね.ううーん.毎回勉強が浅いのかも…


引き継いだC++のプログラムには,ちょっとしたルールを課して作ってあるように見えました.
それは,クラスのpublicなメンバ関数は,他のpublicな関数を参照しないというものです.
意図を汲んでみると,おそらく,publicな関数はクラス外部から定義できてしまうので,それにより望みの機能が意図的であれ故意であれ変わってしまわないようにしているのではないかと.

どれだけ一般なのかわかりませんし,使えるルールなのかはわかりません.小さい実装だからこそ可能なルールかもしれません.
なにかよく知っている方がいればコメントくれるとありがたいです(まだこのブログ成熟どころか卵ですらないんですがね…写真とか写真とか異様に小さい写真とか).


vectorが使えるといいなぁなんて昨日投稿しましたが,同じように,
sstreamをincludeしてostringstreamとかistringstreamとか定義しちゃって,がんばろうと思いました.
文字列苦手ですし.簡単にはto_stringなんてある…みたいな記述も見かけた.
スポンサーサイト



ちょっと日常:三項演算子a?b:c, 列挙体enum, vector, クラスの継承・純粋仮想関数

日常なのであんまり真剣に読まないでね.


突然出てきたらびっくりします.三項演算子.疑問に思う…のがよいかもしれないな.
ただの<条件> ? <真の実行式> : <偽の実行式>
です.これがif()の中にそのまま現れたのです.最初なにかと思いました.
三項演算子?キモッッて中学の頃に見た覚えがあったからすんなり理解できたわけで…


逆に最近にちょっとした記事で見ただけの知識,それが生きたのは列挙体に関して.
列挙体は

enum <識別子> {<要素1>, <要素2>, …} <変数名>;
enum hand {left, right} person;
と書きます.
全然知りませんでした.ちょっと恥ずかしい.
識別子と変数名のどちらかは省略可能.え?意味わかんない…と思ったけど

考えた結果,識別子はクラス名のようなもので,そのクラスの構造を持つものをいろいろ用意できる…いや,だから識別子なんですけど.こっちは容易に理解できるし,私の見たenumもこれだった.変数名はクラスを定義した後に変数を作るのと同じ感覚.
じゃあ識別子を書かないって?役割を持たせた列挙体を一つに限って用意したいとき(があるのか・・?),実現できます.他に使い道は浮かばないので,どう使うかが問題の気がします.

そもそものenumの使い方?中身?としては,例えばhand::leftと書いてみたりするんですが,leftにはint型の0が,rightにはint型の1が列挙変数に関連付けられています.とはいえ,hand = 0;とするのは定義されておらず,hand = (enum hand) 0;という形が標準です.暗黙の型キャストはコンパイラ依存と言えます.
また,switch文ではswitch(hand) { case: left …と書くことができる.


vectorが使えたら私もデータ処理とか楽しめるんじゃないかと思って,やり始めました.
結果はでてないけど.
とりあえずvector.push_backでデータを一個追加することができると知ったよ.どう追加されてるのさ…
一次元データがどう格納されて,push_backやpop_backは最後尾で行われるかとか,そういう点を理解しなきゃいけない.
あと二次元データの扱い方があればそこも勉強しなきゃ.


さて,まとめたかったクラスの継承.そういうものがあるっていうことだけは知ってたけど,まとめて読んだのは初めてだった.

・クラスの継承は":"でおこなう.: public <親クラス名>とかprivate <親クラス名>とか.
親クラスのpublicメンバ関数をpublicで継承したいときにpublic指定,privateで継承したいときにprivate指定するだけ.
・メンバ変数を初期化して継承するには<親クラス名>に続いて","を置いて,<メンバ変数1>(<値1>), <メンバ変数2>(<値2>),…としていく.
・virtualでメンバ関数を仮想関数に.すると継承した子クラスで再定義ができるようになる.
・純粋仮想関数virtual <メンバ関数名> = 0; 関数の実体を定義せず,継承される前提で仕組みを内包させておく使い方だろうか.
・抽象クラスとは,純粋仮想関数などを使って実体を作らないクラス.実体を作れない…そのことを「インスタンス」という言葉を使っていたけど私にはまだわからなかったな.
・public,privateの他にprotectedというものがある.親クラスで使って,その時点ではprivateと同じだが,継承クラスでpublic扱いで継承される.
・他にも,子クラスのpublic内でusing <親クラス名>::;なんてすると親クラスで定義しつつも使えないようにしてあった関数を,親クラスで行った実装を引き継いで使うことができます.これはちょっとした発見だったな.
・あと,親クラスのデストラクタはvirtualにしとかないとね,と.
・他には,this->ってなんだよ!とか.いや,そのままなんですけどね.クラスの実装の中で,メンバ変数をいじるときにthis-><メンバ変数名>と書く・・はず.


こんなとこかな.うーん,文にしてまとめるには多すぎるし何より教科書的な内容だから箇条書きのままで.
それでは.

batファイルを作ることになったメモ

今までbatファイルを(Qt同様に)引き継いで使っていたわけですが,
それを読んだりちょっと変更するだけでなく,自分で作る必要がついに.

改めてbatファイルの様々な構文の,いろいろな使い方というのを知りました.
そのサイトやら,使ってみた方法などをメモしていきます.
ヘッダー(&フッター),コメントアウト,変数の取扱い,for文,ファイル入出力,他のbatファイルの実行,待機までまとめます.
他のファイルの実行,ちょっと説明が怪しいので書かないことにします.そもそもプログラミングの理解が足らないような…

主にこちらを参考にして書きました.
開発に約立つ,BATファイルの書き方・パターン集

batファイルを読み込んでコマンドライン操作をする場合が前提です.打ち込むのが面倒だし間違ってたらすぐ直せるという必要からです.まずは頭に
@echo off
SETLOCAL enabledelayedexpansion
といれちゃってからコメントしましょう.
一行目の@echo offがないと,読み込んでいったものが全てechoされます.つまり,読み込んだ文を一行ずつ,そのまま出力してくれます.邪魔,切る.
次の行のヨクワカラナイ長いやつは,変数の遅延展開を可能にするコマンド.batの環境変数は即時展開と遅延展開というものがあり,値が更新されていくようなものを使う場合...forなど...には遅延展開の宣言が必要です(変数の項で即時展開,遅延展開の書き方を説明します).
遅延展開の宣言は,SETLOCALからENDLOCALまでの間です.頭にSETLOCALを宣言したので,batファイルの最後にENDLOCALしておきます(実際は省略可能のようです).

rem ~~~
コメント化する命令です.
その行の最初にrem(ember)を書けば,行全体が命令ではない文として認識されます.

rem set 変数名=格納する値
set mydomain=amefuriyame
set mypath=fc2.com
set myhtml=%mypath%.%mydomain%

set /a iter1=1
set /a iter1=!iter1!+1
set /a iter1=!iter1!+1
変数を定義します.
setは他にも色々使い方はありますが,変数に関して言えばsetが使われるわけです./a(rithmetic)は,=の後の文を式として読み込むものです.例えば,"1+1+1"という値の入った変数を/aで代入すると3になって格納されます.

%~~%と囲めば,変数の即時展開ができます.これにより,例えばecho %myhtml%とすれば,出てくるのはfc2.com.amefuriyameです.全然ドメインでも何でもないですが.
!~~!と囲めば,変数の遅延展開ができます.これにより,実行されたときに値が変化してくれるので,最後までiter1を読むとecho !iter1!は3と返ってきます.

…実はこの場合,!~~!ではなく%~~%でも同じ結果がでます.ちょっとびっくりしましたが,「実行されたとき」というのが何と対比しているのかが重要でした.比べられるのは「読み込むとき」です.
読み込むときに,読み込んだブロックごと変数を代入してしまうのが即時展開%~~%.読み込むブロックというのは例えばif判定してから真なら実行する中身までの全て.for文で実行する中身の全て.
今回はそういうブロックに相当するのが一行ずつです.さて,ブロックを作ってみましょう…
set iter1=1
(
set /a iter1=!iter1!+1
set /a iter1=!iter1!+1
)
むだにカッコを前後につけるだけです.
この状態で色々なところにecho !iter1!やらecho %iter1%やらやってみると,感覚がつかめると思います.
(set iter1=1もカッコの中に入れてしまうと,echo %iter1%はただのechoと同じになる,という点だけ注意すると比較できるでしょう.)
参考:遅延環境変数とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

さて,for文ですが,いろいろなオプションで様々なことができます.
参考:.bat(バッチファイル)のforコマンド解説。
今回は使った/L,/Fオプションだけ紹介./Lが数値を更新していくfor文,/Fがファイルを扱う文です.
for /L %%i in (1,2,10) do (
echo %%i
set /a twice=%%i*2
echo !twice!
)
for文の変数は%%と2つ重ねて.
(1,2,10)は1から始まり,2ずつ増やし,10を越したら実行しないという意味です.減らすことも可能で,整数です.
/Lを使わない場合,(1,2,10)の代わりに整数リストを配置します.リストは使ってないのでわかりません.参考に示すようなやり方をすればなんとなくでもできます.
参考:新潟工科大学 情報電子工学科 4.2 for文

echo HeaderMsg > file1_3.txt
for /F "skip=4 tokens=1,3 delims=," %%a in (file1.csv) do (
echo %%a
echo %%b >> file1_3.txt
)
ファイルを扱うためのforです.参考:外部ファイルを読み込む
file1.csvの先頭4行をskipし,","で区切って読み,1列目と3列目をaに続く変数に格納する.それを行がなくなるまで繰り返す.と読みます.
aに続く変数に格納ってなんだよ,って話ですが,tokensで指定した個数(今回は,1列目と3列目を格納するので2個)だけ,a,b,c,…と勝手に宣言して格納してくれます.ということで,aをechoして,bをfile1_3.txtに書き出してもらいました.
>1個でファイルは初期化されます.>>と2個になるとファイルの最後尾に追記していく形です.file1_3.txtはHeaderMsgという文字列で初期化されました.その後,file1.csvの3列目だけがfile1_3.txtに記録されます.
以上,ファイル入出力を同時にやりました.

待機するのにwaitもsleepもないということで
ping localhost -n 5 > nul
が提案されています(一番最初に紹介した参考ページ).なんだか,面白い.

pauseというコマンドもあります.pauseは待機ではないですが,入力待ちになるものです.使えばわかります,これかー!,と.

以上,batファイルの加工現場でした.
プロフィール

satsuki

Author:satsuki
記事を消しつつ、ころころ変えながら運用中

最新記事
最新コメント
月別アーカイブ
カテゴリ
訪問者数
検索フォーム
リンク
QRコード
QR