ここでは、C、C++のTipsについて述べる
gettimeofdayを使用します。必要なヘッダは
#include <sys/time.h>
です。使い方は、下記のようにします。
struct timeval t; gettimeofday(&t, NULL); cout<< t.tv_sec + (double)t.tv_usec*1e-6<<" sec"<<endl;
unameを使う。必要なヘッダは
#include <sys/utsname.h>
struct utsname uts; uname(&uts); cout<<uts.nodename<<endl;
インテルコンパイラの場合、INCLUDE環境変数ではなく、CPATH、C_INCLUDE_PATH、CPLUS_INCLUDE_PATHに追加する。
手動で追加する場合は-I pathで指定する。
進行状況のバーグラフを表示する場合などに、端末の画面幅を取得したい場合がある。これはioctl関数を使うと取得できる。
必要なヘッダは、
#include <sys/ioctl.h> #include <unistd.h>
使い方は、
struct winsize winsz; ioctl(STDOUT_FILENO, TIOCGWINSZ, &winzs); cout<<"端末の幅 = "<<win.ws_col<<endl;
処理が終了したことなどをメールを使って知らせたい場合があります。このような場合、SMTPを使って通信をするプログラムを一から書くのは、少し大げさです。以下はsystem関数とmailコマンドを使って送信する方法です。
まず、コマンドラインからfoo@example.com宛に、subject hogehogeという表題でhello worldという内容のメールを送信するには、
echo hello world | mail -s "subject hogehoge" foo@example.com
です。
そこで、これをプログラムからメールを送信するにはsystem関数を使って
system("echo hello world | mail -s \"subject hogehoge\" foo@example.com");
とします。
opendir、readdir、closedirを使う。
必要なヘッダは、
#include <sys/types.h> #include <dirent.h>
まず、opendirでディレクトリを開く。
DIR* dp=opendir("/home/foo/boo/");
エラーがあった場合は、NULLが返される。
次に、readdirで読み込む。NULLになるまで読み込むと、ディレクトリ内のすべてのファイルを取得することができる。
最後にclosedirで閉じておく。
closedir(dp);
DIR* dp=opendir("/home/foo/boo/"); if (dp!=NULL) { struct dirent* dent; do{ dent = readdir(dp); if (dent!=NULL)cout<<dent->d_name<<endl; }while(dent!=NULL); closedir(dp); }
remove関数でどちらも削除できる。
書式は
remove("filename.txt");
成功すると0が返される。
Visual C++系ではgccやborland C++、インテルC++などで使えるπを指定するM_PIが使えません。使えるようにするには、mathライブラリをインクルードする前に_USE_MATH_DEFINESを定義してやります。
#define _USE_MATH_DEFINES #include <cmath>
#ifdefや#ifndefは#ifの特別バージョンです。
#ifdef マクロ名 ~ #else ~ #endif
は
#if defined マクロ名 ~ #else ~ #endif
を
#ifndef マクロ名 ~ #else ~ #endif
は
#if !defined マクロ名 ~ #else ~ #endif
の事です。
#ifdefや#ifndefでelse ifを使う場合は、#elifを利用します。
#if defined マクロ名 ~ #elif defined マクロ名 ~ #else ~ #endif
もしくは、
#ifdef マクロ名 ~ #elif defined マクロ名 ~ #else ~ #endif
とします。
#include <iomanip> cout<<std::setprecision(20)<<t<<"\t"<<x<<endl;
この方法は、当然ofstreamなどにも使えます。
endlやflushメソッドは、バッファを空にしても、それがOSのキャッシュに残ってしまうかもしれません。完全に書き込むには、fsyncを使います。
なお、C++のofstreamには、ファイル記述子がないので、一旦closeを呼び出すのが簡単。もしくは、fopenを使った独自のクラスを書く以外にない。
pubsetbufを使う。pubsetbufがC言語のstdioのsetvbuf関数に相当する。
time_t now; struct tm *tptr; char *weekday[] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"}; now = time(NULL); tptr = localtime(&now);
gettimeofday()関数を使います。
struct timeval tv; struct timezone tz; gettimeofday(&tv,&tz);
getrusage()関数を使います。sys/time.hとsys/resource.hをインクルードしてください。
下記の関数はCPU時間をマイクロ秒で返します。
#include <sys/time.h> #include <sys/resource.h> long int cputime(void) { struct rusage rs; getrusage(RUSAGE_SELF, &rs); return rs.ru_utime.tv_sec * 1000000 + (double)rs.ru_utime.tv_usec; }
getpid()関数を使います。sys/types.hとunistd.hをインクルードしてください。
#include <sys/types.h> #include <unistd.h> pid_t pid=getpid();
なお、getppid()関数はプロセスの親プロセスのプロセスIDを返します。
#include <unistd.h>をインクルードする。
sleep(1)で一秒間眠る。
XORSHIFTアルゴリズムによる乱数は、非常にシンプルなコードでメルセンヌ・ツイスターに近い良質な乱数を生成する。
#include <iostream> #include <cmath> using namespace std; unsigned long xor128(void) { static unsigned long x=123456789,y=362436069,z=521288629,w=88675123; unsigned long t; t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) ); } int main(void) { unsigned long sum=0; for (int j=0;j<1000;j++) { for (int i=0;i<100000;i++) { sum+=xor128()%2; } double ave=double(sum)/(j*100000); cout<<ave<<endl; } return 0; }
本文中のFC4はFedora ProjectのFedora Core 4を、FC5はFedora Core 5を、FC6はFedora Core 6、FC7はFedora Core 7をopenSUSEはNovellのSUSE Linux OSSを表します。
ここに登場するドメイン名やIPアドレスなどはフィクションです。実在の人物・団体等とは一切関係がありません。