目次へもどる  

Google

C、C++ Tips

ここでは、C、C++のTipsについて述べる

Tips一覧

  1. マイクロ秒まで計測するには?
  2. プログラムを実行しているホスト名を取得するには?
  3. インテルコンパイラでインクルードパスを追加するには?
  4. Unixのターミナルの画面幅を取得するには?
  5. プログラムから簡単にメールを送信するには?
  6. Unixでディレクトリ内のファイル一覧を取得するには?
  7. Unix系OSでファイル、ディレクトリを削除するには?
  8. Visual C++でM_PIを使うには?
  9. #ifdefでelse ifは?
  10. coutで出力桁数を指定するには?
  11. ディスクに完全に書き込むには?
  12. ofstreamで書き込みバッファの容量を指定するには?
  13. vectorで多次元配列を実現するには?
  14. ローカルタイムを取得するには?
  15. Unix系OSで実行優先度を取得するには?
  16. Unix系OSでタイムゾーンを取得するには?
  17. Unix系OSでCPU時間を取得するには?
  18. Unix系OSでプロセスIDを取得するには?
  19. インテルコンパイラでsleep関数を使うには?
  20. XORSHIFTによる乱数
  21. intを32ビットに指定するには?

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で指定する。

Unixのターミナルの画面幅を取得するには?

進行状況のバーグラフを表示する場合などに、端末の画面幅を取得したい場合がある。これは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");

とします。

Unixでディレクトリ内のファイル一覧を取得するには?

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);
		}

Unix系OSでファイル、ディレクトリを削除するには?

remove関数でどちらも削除できる。

書式は

remove("filename.txt");

成功すると0が返される。

Visual C++でM_PIを使うには?

Visual C++系ではgccやborland C++、インテルC++などで使えるπを指定するM_PIが使えません。使えるようにするには、mathライブラリをインクルードする前に_USE_MATH_DEFINESを定義してやります。

#define _USE_MATH_DEFINES
#include <cmath>

#ifdefでelse ifは?

#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

とします。

coutで出力桁数を指定するには?

#include <iomanip>
cout<<std::setprecision(20)<<t<<"\t"<<x<<endl;

この方法は、当然ofstreamなどにも使えます。

ディスクに完全に書き込むには?

endlやflushメソッドは、バッファを空にしても、それがOSのキャッシュに残ってしまうかもしれません。完全に書き込むには、fsyncを使います。

なお、C++のofstreamには、ファイル記述子がないので、一旦closeを呼び出すのが簡単。もしくは、fopenを使った独自のクラスを書く以外にない。

ofstreamで書き込みバッファの容量を指定するには?

pubsetbufを使う。pubsetbufがC言語のstdioのsetvbuf関数に相当する。

vectorで多次元配列を実現するには?

ローカルタイムを取得するには?

time_t now;
struct tm *tptr;
char *weekday[] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
now = time(NULL);
tptr = localtime(&now);

Unix系OSで実行優先度を取得するには?

Unix系OSでタイムゾーンを取得するには?

gettimeofday()関数を使います。

struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz); 

Unix系OSでCPU時間を取得するには?

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;
}

Unix系OSでプロセスIDを取得するには?

getpid()関数を使います。sys/types.hとunistd.hをインクルードしてください。

#include <sys/types.h> 
#include <unistd.h>

pid_t pid=getpid();

なお、getppid()関数はプロセスの親プロセスのプロセスIDを返します。

ベクトル化してSSE等を使って計算しやすいコードを書くには?

パイプの使い方

インテルコンパイラでsleep関数を使うには?

#include <unistd.h>をインクルードする。
sleep(1)で一秒間眠る。

XORSHIFTによる乱数

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;
}

makeでコンパイルする

空白ではなく、タブ文字を使うこと。

コンパイル時にmultiple definition of xxxというエラーが出る

.hファイル内にconstパラメータは記述しないこと。 constはcppファイル内に記述する。




本文中のFC4はFedora ProjectのFedora Core 4を、FC5はFedora Core 5を、FC6はFedora Core 6、FC7はFedora Core 7をopenSUSEはNovellのSUSE Linux OSSを表します。

ここに登場するドメイン名やIPアドレスなどはフィクションです。実在の人物・団体等とは一切関係がありません。
実際に使用する際は、各自の環境に合わせて書き換えてください。
もし何か間違いなどありましたらこちらからご連絡ください
リンクに許可は不要です。
Copyright (C) 2007 Chikuma Engineering Co., Ltd. All Rights Reserved.