Ubuntu14.0.4でホスト名とユーザ名を変更する
概要
VMのUbuntu14.0.4でホスト名とユーザ名を変更したのが意外と大変だったのでメモ
以下では、ホスト名も、ユーザ名も、gitアカウントと同じ「ludwig125」にすることを目指した
参考
ホスト名
ホスト名:hostnameコマンドの結果出力するUbuntuのホスト名を指す
ホスト名の変更は簡単だった
- 以下のホスト名を変更するだけ
sudo vim /etc/hostname sudo vim /etc/hosts
反映させるにはUbuntuの再起動が必要
確認
$ hostname ludwig125-virtual-machine
※「-virtual-machine」の部分をつけたほうがホスト名として分かり易いのでつけた
ユーザ名の変更
ユーザ名:whoコマンドで出力されるユーザの名前
ユーザ名の変更はusermodで行う
usermodをする上での問題
しかし、自分のユーザ名を変更しようとしても、自分自身のプロセスがあるので変えられないという問題がある
$ sudo usermod -l ludwig125 <今のユーザ名> usermod: user <今のユーザ名> is currently used by process 1495 $
別のユーザを作る
自分自身のプロセスが動いている状態で自分のユーザ名を変えられないので、別にユーザを作った (もっといい方法があるかもしれない・・・)
- adduserで「temp_user」ユーザを追加
$ sudo adduser temp_user ユーザー `temp_user' を追加しています... 新しいグループ `temp_user' (1001) を追加しています... 新しいユーザー `temp_user' (1001) をグループ `temp_user' に追加しています... ホームディレクトリ `/home/temp_user' を作成しています... `/etc/skel' からファイルをコピーしています... 新しい UNIX パスワードを入力してください: 新しい UNIX パスワードを再入力してください: passwd: パスワードは正しく更新されました temp_user のユーザ情報を変更中 新しい値を入力してください。標準設定値を使うならリターンを押してください フルネーム []: temp 部屋番号 []: 職場電話番号 []: 自宅電話番号 []: その他 []: 以上で正しいですか? [Y/n] y
temp_userにsudo権限を追加
作ったばかりのtemp_userにはsudo権限がないので temp_userでusermodをすると以下のエラーが出た
$ usermod コマンド 'usermod' は '/usr/sbin/usermod' で利用できます '/usr/sbin'がPATH環境変数に含まれていないためコマンドを特定できませんでした。 大抵の場合、お使いのユーザーアカウントに管理者特権がないことが原因です。 usermod: コマンドが見つかりません temp_user@ludwig125-virtual-machine:/home$ useradd コマンド 'useradd' は '/usr/sbin/useradd' で利用できます '/usr/sbin'がPATH環境変数に含まれていないためコマンドを特定できませんでした。 大抵の場合、お使いのユーザーアカウントに管理者特権がないことが原因です。 useradd: コマンドが見つかりません
temp_userでusermodをできるように、予めtemp_userにsudo権限を付けておく
sudoユーザーを追加する方法 - Linux入門 - Webkaru
以下はtemp_userではなく、もとのユーザ権限で実行
usermod -G sudo temp_user
temp_userでログインし直す
ubuntuのユーザをみて、temp_userに切り替える
temp_userでusermod実行
temp_user内で改めてusermodを実行
$ sudo usermod -l ludwig125 <今のユーザ名> usermod: user <今のユーザ名> is currently used by process 1495 $
もとのユーザのプロセスが動いているので、全部killする
sudo kill -9 プロセスID
再度usermodを実行したら、今度はうまくいった
ユーザディレクトリの名前を変更
$ ls /home $ cd /home $ sudo mv もとのユーザ ludwig125 $ ls /home ludwig125 temp_user
whoで確認
[~] $ who ludwig125 :0 2017-12-16 22:42 (:0) ludwig125 pts/5 2017-12-16 22:46 (:0:S.0) ludwig125 pts/13 2017-12-16 22:46 (:0:S.1) [~] $
更に/etc/passwdのユーザディレクトリを変える
$ sudo vim /etc/passwd で ludwig125:x:1000:1000:ludwig125:/home/ludwig125:/bin/bash ↑この/home以下のディレクトリ名をもとのユーザ名から変える
上記までの対応によって生じた問題
トラブル1.VMとホストOSとの間でコピペができない
名前変更後、VMのデータをコピーしてホストOSのWindowsにペーストできないという問題が生じた
ホスト名を変えてしまったのでvmwaretoolsが機能していない可能性がある
いったんVMもホストOSも再起動したらコピペができるようになった
- 参考 vmware toolsとは
VMware Tools の概要 VMware Tools は、仮想マシンのゲスト OS のパフォーマンスを強化し、仮想マシンの管理を改善するユーティリティのスイートです。ゲスト OS に VMware Tools をインストールしておかないと、ゲストで重要な機能を実行できません。VMware Tools をインストールすると、次のような問題が排除または改善されます。 ビデオの解像度が低い カラー深度が不十分 ネットワーク速度の表示が正しくない マウスの動きが制限される コピー アンド ペーストやファイルのドラッグ アンド ドロップができない 音声が出ない ゲスト OS の静止スナップショットを作成する機能が用意される ゲスト OS とホストの時刻が同期される
トラブル2. linuxのグループが変わっていない
グループ名が昔のまま変わっていなかったので変える
usermod -g グループ名 ユーザ名
[/home] $ sudo groupadd ludwig125 [/home] $ sudo usermod -g ludwig125 ludwig125 [/home] $
トラブル3. git に接続できない
名前変更後、gitに接続できない
git pullできない 「Permission denied (publickey).」が出た
[~/git/work] $ git pull Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts. Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. [~/git/work] $
以下を参考に調べて見る
githubで"Permission denied (publickey)."が出た時はssh -Tで繋ぎ直す - Qiita Error: Permission denied (publickey) - User Documentation Git - SSH 公開鍵の作成
[~/git/work] $ ssh -vT git@github.com OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: Connecting to github.com [192.30.255.112] port 22. debug1: Connection established. debug1: identity file /home/ludwig125/.ssh/id_rsa type 1 debug1: identity file /home/ludwig125/.ssh/id_rsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_dsa type -1 debug1: identity file /home/ludwig125/.ssh/id_dsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_ecdsa type -1 debug1: identity file /home/ludwig125/.ssh/id_ecdsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_ed25519 type -1 debug1: identity file /home/ludwig125/.ssh/id_ed25519-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8 debug1: Remote protocol version 2.0, remote software version libssh_0.7.0 debug1: no match: libssh_0.7.0 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr hmac-sha1 none debug1: kex: client->server aes128-ctr hmac-sha1 none debug1: sending SSH2_MSG_KEX_ECDH_INIT debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: RSA 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 debug1: Host 'github.com' is known and matches the RSA host key. debug1: Found key in /home/ludwig125/.ssh/known_hosts:1 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: /home/ludwig125/.ssh/id_rsa debug1: Authentications that can continue: publickey debug1: Trying private key: /home/ludwig125/.ssh/id_dsa debug1: Trying private key: /home/ludwig125/.ssh/id_ecdsa debug1: Trying private key: /home/ludwig125/.ssh/id_ed25519 debug1: No more authentication methods to try. Permission denie [~/git/work] $
ホスト名を変えたからなのか、なぜなのかわからないけれど、git にssh鍵が登録されていないみたい
以前書いた自分のブログを参考にssh鍵を作って登録し直す
登録後
[~/git/work] $ ssh -vT git@github.com OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: Connecting to github.com [192.30.255.113] port 22. debug1: Connection established. debug1: identity file /home/ludwig125/.ssh/id_rsa type 1 debug1: identity file /home/ludwig125/.ssh/id_rsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_dsa type -1 debug1: identity file /home/ludwig125/.ssh/id_dsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_ecdsa type -1 debug1: identity file /home/ludwig125/.ssh/id_ecdsa-cert type -1 debug1: identity file /home/ludwig125/.ssh/id_ed25519 type -1 debug1: identity file /home/ludwig125/.ssh/id_ed25519-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8 debug1: Remote protocol version 2.0, remote software version libssh_0.7.0 debug1: no match: libssh_0.7.0 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr hmac-sha1 none debug1: kex: client->server aes128-ctr hmac-sha1 none debug1: sending SSH2_MSG_KEX_ECDH_INIT debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: RSA 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 The authenticity of host 'github.com (192.30.255.113)' can't be established. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,192.30.255.113' (RSA) to the list of known hosts. debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: /home/ludwig125/.ssh/id_rsa debug1: Server accepts key: pkalg ssh-rsa blen 279 debug1: key_parse_private2: missing begin marker debug1: read PEM private key done: type RSA debug1: Authentication succeeded (publickey). Authenticated to github.com ([192.30.255.113]:22). debug1: channel 0: new [client-session] debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = ja_JP.UTF-8 debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 Hi ludwig125! You've successfully authenticated, but GitHub does not provide shell access. debug1: channel 0: free: client-session, nchannels 1 Transferred: sent 3312, received 1872 bytes, in 0.2 seconds Bytes per second: sent 14182.2, received 8016.0 debug1: Exit status 1 [~/git/work] $
成功 git pullもgit pushもできるようになった! ブログ書いててよかったよ
トラブル4. pip3が使えなくなってた
誤ったインタプリタです: そのようなファイルやディレクトリはありません
pip3を使おうとしたらこんなエラーが
[~/git/work/src/python/memo/pandas] $ pip3 install pandas_ply /home/ludwig125/.pyenv/pyenv.d/exec/pip-rehash/pip: /home/ludwig125/.pyenv/versions/3.5.4/bin/pip3: /home/前のユーザ名/.pyenv/versions/3.5.4/bin/python3.5: 誤ったインタプリタです: そのようなファイルやディレクトリはありません
前のユーザ名のパスを見ようとしている?
解決できないのでpyenvごと削除して作り直す
[~] $ pyenv versions * system (set by /home/ludwig125/.python-version) 3.5.4 [~] $ pyenv uninstall 3.5.4 pyenv: remove /home/ludwig125/.pyenv/versions/3.5.4? yes [~] $ [~] $ pyenv install 3.5.4 Downloading Python-3.5.4.tar.xz... -> https://www.python.org/ftp/python/3.5.4/Python-3.5.4.tar.xz Installing Python-3.5.4... Installed Python-3.5.4 to /home/ludwig125/.pyenv/versions/3.5.4 $ pyenv local 3.5.4で移動
これでpip3を使えるようにになった
[~] $ [~] $ pip3 --version pip 9.0.1 from /home/ludwig125/.pyenv/versions/3.5.4/lib/python3.5/site-packages (python 3.5) [~] $
pythonでseleniumを使う
参考
とりあえず参考になったページを貼っておく
入門、Selenium - Seleniumの仕組み | CodeGrid
Selenium使ってみた(Python) - コンピュータサイエンス系勉強ノート
PythonでSeleniumを使ってスクレイピング (基礎) - Qiita
3秒でわかるSeleniumのつかいかた(Python・ちょっとDjango) - へっぽこびんぼう野郎のnewbie日記
Selenium使ってみた(Python) - コンピュータサイエンス系勉強ノート
準備
seleniumをインストール
$ pip3 install selenium
以下からchromedriverをダウンロード
- Downloads - ChromeDriver - WebDriver for Chrome
- → zipファイルを展開してとりあえず~/に置いた
以下のファイルを実行
$ cat selenium-test.py from selenium import webdriver browser = webdriver.Chrome(executable_path='/home/ludwig125/chromedriver') browser.get('https://www.yahoo.co.jp/')
実行
python3 selenium-test.py
Chromeが起動してyahooのページが表示される
トラブル対応
moduleが無いとかでうまく実行できなかったので、以下を確認し直す
$ sudo apt install python3-pip python3-dev $ pyenv install 3.5.4 $ pyenv local 3.5.4 $ pyenv versions system * 3.5.4 (set by /home/ludwig125/git/work/src/python/.python-version) $
python3のパスを確認
$ which python3 /home/ludwig125/.pyenv/shims/python3 $ /home/ludwig125/.pyenv/shims/python3 --version Python 3.5.4 $
pythonでグラフを描画(matplotlib)
グラフの例(sin関数)
【Python入門】ライブラリmatplotlibの基本的な使い方 - Qiita
[~/git/work/src/python] $ cat test.py import math import numpy as np from matplotlib import pyplot pi = math.pi x = np.linspace(0, 2*pi, 100) y = np.sin(x) pyplot.plot(x, y) pyplot.show() [~/git/work/src/python] $
実行
python3 test.py
以下、これを表示するまでのエラー
エラー対応
参考
matplotlibが描画されない - DISTRICT 37
python - python3 で _tkinter を import したい - スタック・オーバーフロー
ImportError: Importing the multiarray numpy extension module failed. Most likely you are trying to import a failed build of numpy. If you're working with a numpy git repo, try `git clean -xdf` (removes all files not under version control). Otherwise reinstall numpy. Original error was: /usr/local/lib/python2.7/dist-packages/numpy/core/multiarray.so: undefined symbo l: _Py_ZeroStruct [~/git/work/src/python/software-design/saikyu-kouka] $ pip3 install numpy Traceback (most recent call last): File "/usr/local/bin/pip3", line 7, in <module> from pip import main File "/usr/local/lib/python3.6/site-packages/pip/__init__.py", line 26, in <module> from pip.utils import get_installed_distributions, get_prog File "/usr/local/lib/python3.6/site-packages/pip/utils/__init__.py", line 16, in <module> import subprocess File "/usr/local/lib/python3.6/subprocess.py", line 136, in <module> import _posixsubprocess ImportError: /usr/local/lib/python2.7/dist-packages/_posixsubprocess.so: undefined symbol: Py_InitMo dule4_64 や Traceback (most recent call last): File "test.py", line 3, in <module> from matplotlib import pyplot File "/usr/local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 113, in <module> _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup() File "/usr/local/lib/python3.6/site-packages/matplotlib/backends/__init__.py", line 60, in pylab_setup [backend_name], 0) File "/usr/local/lib/python3.6/site-packages/matplotlib/backends/backend_tkagg.py", line 6, in <module> from six.moves import tkinter as Tk File "/usr/local/lib/python2.7/dist-packages/six.py", line 92, in __get__ result = self._resolve() File "/usr/local/lib/python2.7/dist-packages/six.py", line 115, in _resolve return _import_module(self.mod) File "/usr/local/lib/python2.7/dist-packages/six.py", line 82, in _import_module __import__(name) File "/usr/local/lib/python3.6/tkinter/__init__.py", line 36, in <module> import _tkinter # If this fails your Python may not be configured for Tk ModuleNotFoundError: No module named '_tkinter'
などのエラーが出た
もう面倒になったので、pyenvをつくって、入れ直した
$ sudo apt install python3-pip python3-dev $ pyenv install 3.5.4 $ pyenv local 3.5.4 $ pyenv versions system * 3.5.4 (set by /home/ludwig125/git/work/src/python/.python-version) $
python3のパスを確認
$ which python3 /home/ludwig125/.pyenv/shims/python3 $ /home/ludwig125/.pyenv/shims/python3 --version Python 3.5.4 $
追加で必要なライブラリをインストール
$ python3 -m pip install numpy $ python3 -m pip install matplotlib
tkinterが使えることを確認
$ python3 -m tkinter
グラフの例(1次関数)
$ cat y-is-10x.py import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 99, 100) y = x * 10 plt.plot(x, y) plt.show()
実行結果
$ python3 y-is-10x.py
グラフの例(ノイズの入った1次関数)
$ cat noisy_y.py import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 99, 100) f_noisy = np.vectorize(lambda x: x * 10 + np.random.normal(0, 100)) d = f_noisy(x) plt.plot(x, d) plt.show()
実行結果
python3 noisy_y.py
グラフの例(放物線)
$ cat throw.py from math import sin, cos, radians from matplotlib import pyplot as plt def throw(x, y, v0, angle, repeatNum, dt): isSuccess = False xarray = []; yarray = [] vx = v0*cos( radians(angle) ) vy = v0*sin( radians(angle) ) ax = 0.0 ay = -9.8 for i in range(repeatNum): x = x + (vx + ax*dt/2)*dt y = y + (vy + ay*dt/2)*dt vx = vx + ax * dt vy = vy + ay * dt xarray.append(x) yarray.append(y) return (xarray, yarray, isSuccess) def prepareFigureArea(): plt.figure(figsize=(5, 5)) plt.xlim([0, 5]) plt.ylim([0, 5]) plt.xlabel('X - Axis (m)') plt.ylabel('Y - Axis (m)') return x1, y1, isSuccess = throw(0, 0, 6, 35, 500, 0.01) x2, y2, isSuccess2 = throw(0, 0, 6, 45, 500, 0.01) x3, y3, isSuccess3 = throw(0, 0, 6, 55, 500, 0.01) x4, y4, isSuccess3 = throw(0, 0, 6, 70, 500, 0.01) prepareFigureArea() plt.plot(x1, y1, 'bo-', x2, y2, 'ro-', x3, y3, 'ko-', x4, y4, 'yo-') plt.legend(['35 deg.', '45 deg.', '55 deg.', '70 deg.']) plt.show()
実行結果
python3 throw.py
以下が必要だったのでpip3 install
$ pip3 install six $ pip3 install pyparsing $ pip3 install cycler $ pip3 install python-dateutil --upgrade
matplotlibの仕様
グラフの点や線の形
グラフの色
matplotlib参考
MSGPACK_DEFINEが32個までしか対応していない問題
msgpackについては以下を参照
問題
MSGPACK_DEFINEで33個以上の引数を取ることができなかった
msgpackのバージョン
現在のmasterのバージョンは2.1.5
https://github.com/msgpack/msgpack-c/blob/master/CHANGELOG.md
MSGPACK_DEFINEとは
保存したいクラスのメンバ変数を、MSGPACK_DEFINEマクロに入れると、 自動でシリアライズ/デシリアライズできる
https://github.com/msgpack/msgpack-c/blob/master/QUICKSTART-CPP.md#user-defined-classes
You can use serialize/deserializes user-defined classes using MSGPACK_DEFINE macro.
ソースコード
MSGPACK_DEFINEの数が32のファイル
[~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ cat msgpack_define_before-expand32.cpp #include <msgpack.hpp> #include <vector> #include <string> #include <iostream> class myclass { public: std::string var[32]; MSGPACK_DEFINE( var[0], var[1], var[2], var[3], var[4], var[5], var[6], var[7], var[8], var[9], var[10], var[11], var[12], var[13], var[14], var[15], var[16], var[17], var[18], var[19], var[20], var[21], var[22], var[23], var[24], var[25], var[26], var[27], var[28], var[29], var[30], var[31]); myclass() { var[0] = "0"; var[1] = "1"; var[2] = "2"; var[3] = "3"; var[4] = "4"; var[5] = "5"; var[6] = "6"; var[7] = "7"; var[8] = "8"; var[9] = "9"; var[10] = "10"; var[11] = "11"; var[12] = "12"; var[13] = "13"; var[14] = "14"; var[15] = "15"; var[16] = "16"; var[17] = "17"; var[18] = "18"; var[19] = "19"; var[20] = "20"; var[21] = "21"; var[22] = "22"; var[23] = "23"; var[24] = "24"; var[25] = "25"; var[26] = "26"; var[27] = "27"; var[28] = "28"; var[29] = "29"; var[30] = "30"; var[31] = "31"; } }; int main(void) { std::vector<myclass> vec; // add some elements into vec... vec.push_back(myclass()); // you can serialize myclass directly msgpack::sbuffer sbuf; msgpack::pack(sbuf, vec); msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size()); msgpack::object obj = oh.get(); // you can convert object to myclass directly std::vector<myclass> rvec; obj.convert(rvec); for(std::vector<myclass>::iterator it = rvec.begin(); it != rvec.end(); ++it) { for(int i = 0; i < 32; i++) { std::cout << (*it).var[i] << std::endl; } } } [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $
コンパイルと実行結果
[~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ g++ -Ipath_to_msgpack/include msgpack_define_before-expand32.cpp [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ ./a.out 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $
これはできる
MSGPACK_DEFINEの数が33のファイル
上のファイルで33個目を追加するとコンパイルに失敗
コンパイルエラー抜粋
/usr/local/include/msgpack/v1/adaptor/detail/cpp03_define_array.hpp:4468:171: note: template argument deduction/substitution failed: In file included from /usr/local/include/msgpack/adaptor/define.hpp:13:0, from /usr/local/include/msgpack/type.hpp:25, from /usr/local/include/msgpack.hpp:18, from msgpack_define_before-expand33.cpp:1: msgpack_define_before-expand33.cpp:10:5: note: candidate expects 32 arguments, 33 provided MSGPACK_DEFINE( ^ In file included from /usr/local/include/msgpack/v1/adaptor/define.hpp:14:0, from /usr/local/include/msgpack/adaptor/define.hpp:15, from /usr/local/include/msgpack/type.hpp:25, from /usr/local/include/msgpack.hpp:18, from msgpack_define_before-expand33.cpp:1:
MSGPACK_DEFINEの定義
return define_array<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31>(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31);
- MSGPACK_DEFINEで呼んでいる関数には32個までしか対応していない
対応策
考えられる対応策は以下の3つ
以下詳細を説明
案1.c++11にする
c++11なら出来るらしい
msgpackの1.0以上、かつc++11だったら33個以上もできそう https://github.com/msgpack/msgpack-c/issues/11
for c++98, we can't extend it easily, all we can do is just write extra specialization for more args. but for c++11, we can use variadic template to break it, although, there is limit, but it's compiler's business.
これができるならそれで問題ない
c++11でコンパイルが通ることを確認
上でコンパイルエラーになったmsgpack_define_before-expand33.cppをc++11でコンパイル
[~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ g++ -Ipath_to_msgpack/include -std=c++11 msgpack_define_before-expand33.cpp [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ ./a.out 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $
案2.MSGPACK_DEFINEを入れ子にする
- 例えば、stuct Aに33個以上の項目を入れてまとめてMSGPACK_DEFINEをしようとすると失敗する
- そこで、別にstruct Bを用意して、その中に項目を入れて、MSGPACK_DEFINEし、さらにそのstructBをstructAの一要素とすれば(入れ子にすれば)、それぞれのstructの項目数は32個を超えずに済む
- 多分これでもできそうだが、入れ子になるのが気持ち悪かったので試してない
案3.拡張版のMSGPACK_DEFINEを作成する
- msgpack 0.5ではかんたんだったけど、最新版は難しい
手順1.拡張版ファイルの作成
https://github.com/msgpack/msgpack-c/tree/315bbd4b40ba5b21bfaeced0e5b7688d833a5b91/erb/v1
ここのerbのGENERATION_LIMIT = 31を40とかに書き換える
今回上のソースコードで使っているのはarrayだけなので、arrayとそこでつかっているtupleだけ増やしたファイルを用意すればいい(mapは不要) なので、以下のファイルのLIMITを40とかに書き換える
- cpp03_msgpack_tuple_decl.hpp.erb
- cpp03_msgpack_tuple.hpp.erb
- cpp03_define_array_decl.hpp.erb
- cpp03_define_array.hpp.erb
あとは、以下のファイルを実行すれば、修正したerbをもとに拡張版のヘッダファイルが自動で作成される
https://github.com/msgpack/msgpack-c/blob/315bbd4b40ba5b21bfaeced0e5b7688d833a5b91/preprocess
rubyが無いと言われたので以下でインストール
# apt-add-repository ppa:brightbox/ruby-ng // レポジトリの追加 # apt-get update // # apt-get install ruby2.2 // ruby(バージョン)のインストール
手順2.作ったファイルでライブラリのファイルを置き換える
これで作ったファイルを実際のmsgpackファイルと置き換える
- 以下のファイルをつくったファイルと置き換える
- /usr/local/include/msgpack/v1/adaptor/detail
これで実行すると、拡張版を使って33以上の項目もMSGPACK_DEFINEできる
[~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ cat msgpack_define_expand33.cpp #include <msgpack.hpp> #include <vector> #include <string> #include <iostream> class myclass { public: std::string var[33]; MSGPACK_DEFINE( var[0], var[1], var[2], var[3], var[4], var[5], var[6], var[7], var[8], var[9], var[10], var[11], var[12], var[13], var[14], var[15], var[16], var[17], var[18], var[19], var[20], var[21], var[22], var[23], var[24], var[25], var[26], var[27], var[28], var[29], var[30], var[31], var[32]); myclass() { var[0] = "0"; var[1] = "1"; var[2] = "2"; var[3] = "3"; var[4] = "4"; var[5] = "5"; var[6] = "6"; var[7] = "7"; var[8] = "8"; var[9] = "9"; var[10] = "10"; var[11] = "11"; var[12] = "12"; var[13] = "13"; var[14] = "14"; var[15] = "15"; var[16] = "16"; var[17] = "17"; var[18] = "18"; var[19] = "19"; var[20] = "20"; var[21] = "21"; var[22] = "22"; var[23] = "23"; var[24] = "24"; var[25] = "25"; var[26] = "26"; var[27] = "27"; var[28] = "28"; var[29] = "29"; var[30] = "30"; var[31] = "31"; var[32] = "32"; } }; int main(void) { std::vector<myclass> vec; // add some elements into vec... vec.push_back(myclass()); // you can serialize myclass directly msgpack::sbuffer sbuf; msgpack::pack(sbuf, vec); msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size()); msgpack::object obj = oh.get(); // you can convert object to myclass directly std::vector<myclass> rvec; obj.convert(rvec); for(std::vector<myclass>::iterator it = rvec.begin(); it != rvec.end(); ++it) { for(int i = 0; i < 33; i++) { std::cout << (*it).var[i] << std::endl; } } } [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $
コンパイルと実行
[~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ g++ -Ipath_to_msgpack/include msgpack_define_expand33.cpp [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $ ./a.out 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ← 33個目が使えている! [~/git/work/src/cpp/msgpack/my_sample/msgpack_define_expand] $
c++のメモ
概要
c++についての自分用のメモ書き
g++
g++ がサポートしている規格
$ g++ --version g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ -v --help 2>/dev/null | grep -E "^\s+\-std=.*$" -std=<standard> Assume that the input sources are for <standard> -std=f2003 Conform to the ISO Fortran 2003 standard -std=f2008 Conform to the ISO Fortran 2008 standard -std=f2008ts Conform to the ISO Fortran 2008 standard -std=f95 Conform to the ISO Fortran 95 standard -std=gnu Conform to nothing in particular -std=legacy Accept extensions to support legacy code -std=c++03 Conform to the ISO 1998 C++ standard revised by -std=c++0x Deprecated in favor of -std=c++11 -std=c++11 Conform to the ISO 2011 C++ standard -std=c++1y Conform to the ISO 201y(7?) C++ draft standard -std=c++98 Conform to the ISO 1998 C++ standard revised by -std=c11 Conform to the ISO 2011 C standard (experimental -std=c1x Deprecated in favor of -std=c11 -std=c89 Conform to the ISO 1990 C standard -std=c90 Conform to the ISO 1990 C standard -std=c99 Conform to the ISO 1999 C standard -std=c9x Deprecated in favor of -std=c99 -std=gnu++03 Conform to the ISO 1998 C++ standard revised by -std=gnu++0x Deprecated in favor of -std=gnu++11 -std=gnu++11 Conform to the ISO 2011 C++ standard with GNU -std=gnu++1y Conform to the ISO 201y(7?) C++ draft standard -std=gnu++98 Conform to the ISO 1998 C++ standard revised by -std=gnu11 Conform to the ISO 2011 C standard with GNU -std=gnu1x Deprecated in favor of -std=gnu11 -std=gnu89 Conform to the ISO 1990 C standard with GNU -std=gnu90 Conform to the ISO 1990 C standard with GNU -std=gnu99 Conform to the ISO 1999 C standard with GNU -std=gnu9x Deprecated in favor of -std=gnu99 -std=iso9899:1990 Conform to the ISO 1990 C standard -std=iso9899:199409 Conform to the ISO 1990 C standard as amended in -std=iso9899:1999 Conform to the ISO 1999 C standard -std=iso9899:199x Deprecated in favor of -std=iso9899:1999 -std=iso9899:2011 Conform to the ISO 2011 C standard (experimental
引数
引数を2倍して出力する
参考 - C++で文字列を数値に変換する方法 - C++と色々 - http://www7b.biglobe.ne.jp/~robe/cpphtml/html03/cpp03042.html
https://github.com/ludwig125/work/blob/master/src/cpp/test/argv.cpp
#include <iostream> #include <stdlib.h> using namespace std; int main(int argc, char** argv) { for(int i = 1; i < argc; i++){ cout << "argv "<< i << " : " << argv[i] << endl; cout << "double argv: " << atoi(argv[i])*2 << endl; } return 0; }
実行結果
$ g++ argv.cpp [~/git/work/src/cpp/test ] $ ./a.out 13 83 argv 1 : 13 double argv: 26 argv 2 : 83 double argv: 166
型変換
- 変数の型変換
型を確認
#include <iostream> #include <stdlib.h> #include <typeinfo> using namespace std; int main(int argc, char** argv) { int a,b; for(int i = 1; i < argc; i++){ cout << "argv "<< i << " : " << argv[i] << endl; } // 引数の型 cout << typeid(argv[1]).name() << " : " << argv[1] << endl; a = atoi(argv[1]); b = atoi(argv[2]); // 変換後の型 cout << typeid(a).name() << " : " << a << endl; return 0; }
実行結果
$ ./a.out 10 30 argv 1 : 10 argv 2 : 30 Pc : 10 i : 10
typeidの出力
Uses of typeid in C++ - Codeforces
bool = b char = c unsigned char = h short = s unsigned short = t int = i unsigned int = j long = l unsigned long = m long long = x unsigned long long = y float = f double = d long double = e string = Ss int[] = A_i double[] = A_d vector<int> = St6vectorIiSaIiE
c++のstringへの変換について
to_stringが使えない
あまり考えずにto_stringを使おうとしたら、以下のコンパイルエラーが出た
error: ‘to_string’ is not a member of ‘std’
c++11にするとか、コンパイル時の指定が必要とか書いてある c++ - "to_string" isn't a member of "std"? - Stack Overflow
面倒なので他の方法を探してみる
stringstreamを使う
stringstreamを使った方法が見つかった
参考 - [O] C++ で int 型の値を string 型にするときは stringstream - 文字列⇔数値 - code snippets - C++11で数字→文字列はstd::to_string()、文字列→数字はstd::stoi()とかstd::stod()とか - minus9d's diary
やってみる
超適当なコード
$ cat stringToint.cpp #include <iostream> #include <string> #include <sstream> int main(void) { int a = 3; float b = 3.14; double c = 2.99792458; std::string d= "this is test"; std::string str; std::stringstream ss; ss << a; str = ss.str(); std::cout << str << std::endl; ss.str(""); ss << b; str = ss.str(); std::cout << str << std::endl; ss.str(""); ss << c; str = ss.str(); std::cout << str << std::endl; ss.str(""); ss << d; str = ss.str(); std::cout << str << std::endl; }
実行結果
$ g++ stringToint.cpp $ ./a.out 3 3.14 2.99792 this is test
vector
vectorのソート
参考: - http://blog.sarabande.jp/post/62062199465 - http://kaworu.jpn.org/cpp/std::sort
https://github.com/ludwig125/work/blob/master/src/cpp/test/sort_vector.cpp
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { vector<int> v; v.push_back ( 3 ); v.push_back ( 4 ); v.push_back ( 1 ); v.push_back ( 2 ); std::sort(v.begin(), v.end(), std::greater<int>() ); for(vector<int>::iterator it = v.begin(); it != v.end(); it++){ cout << *it << endl; } return 0; }
実行結果
[~/git/work/src/cpp/test ] $ ./a.out 4 3 2 1 [~/git/work/src/cpp/test ] $
文字列を受け取って1文字ずつvectorに格納
#include <iostream> #include <string> #include <vector> using namespace std; int main() { string str; getline(cin,str); string tmp; // 'abcde'のような文字列を一文字ずつvectorに格納 vector<string> v; for(int i = 0; i < (int)str.size(); i++){ char ch = str[i]; cout << ch << " " << endl; // v.push_back(string(ch)); // 直接charをvectorに格納しようとしたらコンパイルエラーになったのでstringの変数に入れた tmp = ch; v.push_back(tmp); } cout << "output vector" << endl; for(vector<string>::iterator it = v.begin(); it != v.end(); it++){ cout << *it << endl; } return 0; }