スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

C++のstd::cinを思い通りに動作させる。

参考サイト様: http://takagi.in/modules/cpp_guide5/index.php?id=7



散々悩んだstd::cinのoperator>>とgetlineの使い分け…
しかしそれはC言語よりの使者、「char[]」によりあっけなく解決いたしました。

もうstd::cinの1行取得が我々を悩ませる必要はありません!!


だめな例
std::string line;
std::getline(std::cin, line); // aa bb と入力
std::string hoge;
std::cin >> hoge; // 入力すっとばされて「bb」

これはstd::cinによる入力時に
バッファが現地点から空白前までしか読み飛ばされないからです。
つまりgetlineをした時点で、std::string lineは「aa bb」になりますが、
バッファには「aa 」まで読み飛ばしたまでも「bb」が残ります。

そして次の入力待ち「std::cin >> hoge;」(いわゆるoperator>>)が
バッファに残った「bb」を「なんだ、もう既に入力されてるじゃん」と解釈され、
入力スキップされます。(hogeは"bb"になる)

解決方法
char cline[1023];
std::cin.getline(line, sizeof(line)); // aa bb と入力
std::string line(cline); // 内容をstd::stringに持ち直し
std::string hoge;
std::cin >> hoge; // 入力待機

std::getlineとstd::cin.getlineは同じものと思っておいてください。
(少なくともここでは)

これでなぜ入力スキップされないのでしょうか…?
それはstd::cin.getline(line, sizeof(line))で
std::cinに明示的に「sizeof(line)分読み飛ばしてね」と命令しているからです!!

空白とか関係ありません、sizeof(line)分きっかり読み進めるからです。

最後に「cline」はchar[]型なのでstd::stringに持ち直しています。


以上!



あいやはプログラミング仲間を探しています。
スポンサーサイト

【141日目】Vimで安心する編集生活

本記事は【Vim Advent Calendar 2013】の【141日目】です。
前回は manga_osyoさん の
【140日目】gtk 環境だと remote_foreground() がうまく動作しない  でした。



Vimの便利な設定集めました!



vimを安心編集環境にするためのオプションを
helpとか見ながら構築してみました!


※本記事でなにか損害が出たとしても
あいやさんは責任を取れません。


"-- バックアップディレクトリとかを設定してみる --"
 vimでのバックアップディレクトリは
set backup
set backupdir=パス or let &backupdir = パス文字列

という形で設定されます。

通常backupdirを設定しない場合は
hoge.txtのバックアップはhoge.txt~という具合に
カレントディレクトリに置き捨てされます。

ということで安心設定を羅列してみます。
" ファイル(hoge.txt~)のバックアップ先を指定
set backup
set backupdir=~/.backup/vim_backup/

" ファイルを再度開きなおしした場合に開いていた位置を記憶(swpファイル)
set directory=~/.backup/vim_backup/view

" ファイルを再度開き直した場合に前回のundo情報をレストア
set undofile
set undodir=~/.backup/vim_backup/undo


これで設定は完了です。


"-- バックアップディレクトリとかを見やすく設定してみる --"
 vimでのバックアップディレクトリは
set backup
set backupdir=パス or let &backupdir = パス文字列

という形で設定されます。(もう一度)

 しかしどんなに区分けしていっても
皆様が長きVim人生を歩む予定ならば
いくつもの.vimrcへの設定項目で埋もれていってしまうでしょう。


というわけで考えてみた解決方法です。


" 変数として冒頭に記述しておく
 例えばbackupdirを.vimrc中弦に設定する。
そんな場合にいちいち検索して該当項目を探すのは嫌です。
ということで
設定項目と似たような名前でローカル変数に記憶する。
その変数は.vimrc冒頭に書く。

その例です。
ここでは.vimrcで使いまわす値も変数に設定しています。
let s:isWindows = has('win32') || has('win64')
let s:isCygwin = has('win32unix')
let s:isUnix = has('unix') && !has('win32unix')
let s:isMac = has('mac')
let s:isUbuntu = match(system('uname -a'), 'Ubuntu') != -1

let s:backupdir = expand('~/.backup/vim_backup')
let s:directory = s:backupdir.'/swp'
let s:undodir = s:backupdir.'/undo'
let s:viewdir = s:backupdir.'/view'

let s:username = expand('$USER')
let s:groupname = expand('$USER') " $GROUPがねえ in Ubuntu and Cygwin.
::
:: (以下設定が続く)
::
set backup
let &backupdir = s:backupdir
let &directory = s:directory
set &undodir = s:undodir
autocmd BufWinLeave ?* silent mkview " viewを保存
autocmd BufWinEnter ?* silent loadview
::
::
::

 s:groupnameがおかしいのは気にしないでください。
なおswp設定でset swpみたいなことをしていないのは
swpファイルが作られるのがVimのデフォルト設定になっているからです。



"-- おまけ --"
 このバックアップ設定だと、直前の内容しかバックアップされません。
ということで保存したファイルを分毎にバックアップする設定を書きました。
※これは「現在の内容をバックアップディレクトリにも保存する」設定であって
「保存前の内容をバックアップする」設定ではありません。

※ディスク容量圧迫注意、いっぱいになってしまったら適度に削除してあげてください。
function! UpdateBackupByDate() "{{{
let l:dailydir = s:backupdir . '/' . strftime("%Y-%m-%d")
if !isdirectory(l:dailydir)
call mkdir(l:dailydir, 'p', 0755)
let r = system(printf('chown -R %s:%s %s', s:username, s:groupname, l:dailydir))
endif

let filepath = split(expand('%'), '/')
let filename = filepath[len(filepath)-1] . strftime('_at_%H:%M')
execute 'write! '.l:dailydir.'/'.filename
endfunction "}}}
autocmd BufWritePre ?* silent call UpdateBackupByDate()





本日のVim活、終了。




" 放課後Vimタイム(指摘の追加) "
--------------------------------------------------------------------------------------------------------------------------------------------------
manga_osyo : autocmd BufWinLeave ?* silent mkview " viewを保存
autocmd BufWinEnter ?* silent loadview 04/21 00:48
--------------------------------------------------------------------------------------------------------------------------------------------------
manga_osyo : ここら辺、augroup 使ったほうがよさがある 04/21 00:49
--------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------
manga_osyo : >let s:isUbuntu = match(system('uname -a'), 'Ubuntu') != -1
これも起動時に system() が走るのが気になった 04/21 00:51
--------------------------------------------------------------------------------------------------------------------------------------------------
aiya000 : お、system()走るとやっぱり重くなりますか…。 04/21 00:53
--------------------------------------------------------------------------------------------------------------------------------------------------
manga_osyo : Windows だと特にそうですね 04/21 00:54
--------------------------------------------------------------------------------------------------------------------------------------------------
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。