■ IO
■ fwrite
SYNTAX
size_t fwrite(
const void *buf // 書き込みデータのポインタ
size_t sz // バイト長さ
size_t n // データ数
FILE *fp // FILEポインタ
);
RET
OK : 書き込んだデータ個数( バイトではない )
ERROR : nより小さな値
DESC
ファイルへ size バイトのデータを n 個書き込み
static unsigned char data[ 1024 * 512 * 4 ];
glReadPixels(
0, 0,
1024, 512,
GL_RGBA,
GL_UNSIGNED_BYTE,
data
);
FILE *fp = fopen( "d:/capture.raw", "wb" );
fwrite( data, sizeof(data), 1, fp );
fclose( fp );
■ fread
SYNTAX
size_t fread(
void *ptr, // 格納先の Buffer
size_t size, // 1 つの data size
size_t nr, // data の個数
FILE *stream // 読みこみ先の stream
);
DESC
stream ポインタで指定されたストリームから nr 個のデータを読み込み
ptr で与えられた場所に格納する
個々のデータは size バイトの長さを持つ
WARNING
文字とおり, 指定した Size しかよまないので, printf(); をするときは '\0' を忘れずに
REF
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/fread.3.html
{
char buf[256];
memset( buf, 0, sizeof(buf) );
FILE *fp = fopen( "d:/test.txt", "r" );
// 日本語だと どうなるか TEST
// ERROR
// sizeof(char) == 1 なので [い] しか読まれない
// そもそも fgets() のがいいかも
fread( buf, sizeof(char), 2, fp );
printf( buf );
fclose( fp );
}
■ fprintf
SYNTAX
fprintf( FILE *, const char *format, ... )
fprintf( fp, "%32s%4d", n->str, isLeaf );
■ string
■ strlen
SYNTAX
int strlen( const char * );
DESC
文字数をかえす ( Buffer Size ではない )
"\0" はカウントしない
{
char buf[256];
sprintf( buf, "%s", "abc" );
// RET: 3
strlen( buf );
}
WARNING
strlen の \0 忘れ
ERROR
char *p = malloc( strlen(str) );
// error;
strcpy(p, str);
■ strdup
SYNTAX
char *strdup(char *DST, const char *SRC);
■ strcpy
SYNTAX
char *strcpy(char *DST, const char *SRC);
DESC
src ( \0 含む )を dst へコピー
RET
dst の先頭ポインタ
const char *src = "test";
int nr = strlen(src);
char *dst = (char *)malloc( nr+1 );
strcpy( dst, src );
■ strlcpy
SYNTAX
size_t strlcpy(
char *dst,
const char *src,
size_t size
);
DESC
セキュアな strcpy
src の指すアドレスから最大で size - 1 バイトの文字列を dst にコピーする。
また dst の指す文字列が必ずヌル文字で終わるようにする。
dst が char 配列の場合に sizeof(dst) を size として指定すればバッファオーバーランしないことが保証される。
char path[ NR ];
strlcpy( path, src, NR );
■ strchr
SYNTAX
char *strchr(const char *str, int c );
DESC
文字列 str から 文字 c を検索してそのアドレスを返す。
c は最初に見つかったアドレスを返す。
後ろから検索するには strrchr を使う。
RET
NULL : search が c に含まれない
!NULL : str の中の c のアドレス
if ( strchr( "test.bmp", '.' ) != NULL ) {
}
■ strrchr
SYNTAX
char *strrchr(const char *str, int c );
if ( strrchr( "d:/foo/test.bmp", '/' ) != NULL ) {
}
■ strstr
SYNTAX
char *strstr( const char *str, const char *search );
DESC
文字列 str から search を検索してマッチした場合はその先頭アドレスを返す
search は \0 を含めずに検索する
RET
NULL : search が str に含まれない
str : search が長さ 0 の場合は str がかえる
char *s = strstr( "test.bmp", ".bmp" );
// .bmp
ptintf( "%s", s );
■ strncpy
SYNTAX
char *strncpy(
char *dst,
const char *src,
size_t n
);
DESC
文字型配列 dst に文字列 src を先頭から n 文字コピー
dst と src が重なっている場合には動作は未定義
strlen( src ) >= n なら
n 文字をコピーするが '\0' の自動付加はしない
src : [a][b][c][d][e]
dst : [ ][ ][ ][ ]
strncpy( dst, src, sizeof(dst)-1 );
dst : [a][b][c][ ]
// strlen( src ) < n なら、残りの文字を '\0' で埋める
src : [a][b]
dst : [ ][ ][ ][ ]
strncpy( dst, src, sizeof(dst)-1 );
dst : [a][b][\0][ ]
// まとめ
// 0 で padding して
// sizeof(dst) - 1 文字のみ Copy すること
char dst[4];
memset( dst, 0, sizeof(dst) );
strncpy( dst, "abcedf", sizeof(dst)-1 );
// BAD
// BufferOverRun
//::strncpy( dst, "abcedf", sizeof(dst) );
printf( "%s", dst );
■ strtod
SYNTAX
double strtod(const char *STR, char **TAIL);
float strtof(const char *STR, char **TAIL);
RET
0 : Fail
!0 : 数値
正しい値が表現可能な値の範囲外であるとき
値の符号に従って
正または負のHUGE_VALを返し
errnoにはマクロERANGEの値を格納する。
正しい値がアンダーフローを起こすときには0を返し
errnoにはマクロERANGEの値を格納する
DESC
文字列を double | float 型に変換して返す。
{
char *e;
char s[32] = "124.5";
double x = strtod(s, &e);
if (errno != ERANGE) {
printf("変換数値=%f\n", x);
// 間違っていたら何かをさす
if (*e != '\0') {
printf("変換不可能部分=%s\n", e);
}
}
else if (x == HUGE_VAL) {
printf("double値で表現できる値を超えました\n");
}
return 0;
}
sprintf_s と sprintf の違い
sprintf_s は書式指定文字列の有効な書式指定文字をチェックしますが
sprintf は書式指定文字列またはバッファが NULL ポインタかどうかのみをチェックをする。
いずれかのチェックが失敗した場合
「パラメータの検証」に説明されているように
無効なパラメータ ハンドラが呼び出されます
実行の継続が許可された場合
関数は -1 を返し
errno を EINVAL に設定します
sprintf_s は
出力バッファのサイズを文字数で指定する長さパラメータを受け取ります
バッファが小さすぎて出力テキストを格納できないなら
バッファは
空の文字列に設定され
無効なパラメータ ハンドラが呼び出されます
snprintf とは異なり
sprintf_s では
必ずバッファは null で終わります (バッファ サイズがゼロでない限り)
}
EX
{
// Buffer Size = 8
char buf[] = "1234567";
int ret = _snprintf_s( buf, sizeof(buf), sizeof(buf)-1, "foo" );
int ret = _snprintf_s( buf, sizeof(buf), _TRUNCATE, "foo" );
myas( ret != -1, "切り捨てられたけど, ダイジョーブ ?" );
if ( ret == -1 ) {
printf( "切り捨てられた\n" );
}
else {
printf( "%d + 1 文字かきこみました\n", ret );
}
}
■ jump
通常の関数 の return をさけるために使う
// longjmp の戻り先を指定する
int setjmp( jum_buf env )
int longjmp( jum_buf env, int val )
■ time
日付, 時刻 をあつかう
■ clock
SYNTAX
clock_t clock();
DESC
プログラム開始時からの経過時間( msec )をかえす。
秒単位にするには macro `CLOCKS_PER_SEC'. でわる
clock_t, time_t は時間をあらわす算術型
RET
単位
machine-dependent macro `CLOCKS_PER_SEC'.
未定義なら
(clock_t)`-1'
clock_t s = clock();
system( "timeout 3" );
clock_t dt = clock() - s;
printf("%d sec\n", dt / CLOCKS_PER_SEC );
printf("%d msec\n", dt );
■ difftime
SYNTAX
double difftime( time_t t2, time_t t1 )
DESC
経過時間( 秒 )をかえす
時間を表す構造体 struct tm
struct tm {
int tm_sec; // 秒
int tm_min; // 分
int tm_hour; // 時
int tm_mday; // 日
int tm_mon; // 月( 1月=0 )
int tm_year; // 西暦年 - 1900
int tm_wday; // 曜日( 日=0 )
int tm_yday; // 日(年を通して)
int tm_isdst; // サマータイムフラグ
};
■ time
SYNTAX
time_t time( time_t * )
DESC
現在の時間をかえす
■ asctime
SYNTAX
char *asctime( const struct tm *tp )
DESC
文字列表現としてかえす
time_t t = time( NULL );
// Sat Jun 23 15:39:46 2012
printf( "%s\n", asctime( localtime(&t) ) );
■ localtime
SYNTAX
struct tm *localtime(time_t *CLOCK);
DESC
convert time to local representation
mktime' is the inverse of `localtime'.
■ mktime
SYNTAX
time_t mktime(struct tm *);
DESC
convert time to arithmetic representation
■ memory
■ memcpy
SYNTAX
void* memcpy(
void *dst,
const void *src,
size_t N);
DESC
N バイトを src から dst へコピーする。
src と dst の指す領域が重複する場合の処理は未定義
RET
dst のアドレス
■ memmove
SYNTAX
void *memmove(
void *dst, // Copy 先
const void *src, // Copy 元
size_t n // コピーバイト数
);
DESC
dst の先頭から n 文字分 src をコピーする
strcpy()と異なり空文字('\0')を付加しない
src を単なるメモリブロックとして扱うため
途中に空文字('\0')も含めてコピーを続ける
dst と src が重なっているときの動作は memcpy() では未定義ですが、
このmemmove() では正しくコピー(つまり移動)がされる
■ memcmp
SYNTAX
int memcmp(
const void *buf1,
const void *buf2,
size_t n
);
DESC
buf1 と buf2 を先頭から n バイト分比較する
比較は unsigned char としてされる
buf1 と buf2 をメモリブロックとして扱うため
空文字 \0 を含んでいても比較を続ける
RET
> 0 buf1 > buf2
< 0 buf1 < buf2
==0 buf1 = buf2
POINT
型ごとの内部表現の違いを調べるときにも使える。
// int < -> float の mem layout の違いがわかる. -> 0 は同じ 1 は異なる.
{
int i = 1;
// 型変換. ( 01 の並びが変わる ( 表現方法がかわる ) )
float f = i;
// 中身を見てみる.
memDump( &i );
memDump( &f );
// ここでも型変換がおきるらしい.
if ( f == i ) {
printf( "same\n" );
}
}
■ memset
SYNTAX
void memset( void *adr, int c, size_t n );
DESC
buf の先頭から n バイト分 c をセット
adr: unsigned char *型にキャストされ、
c: unsigned char型にキャストされる
■ malloc
SYNTAX
void *malloc( size_t sz );
DESC
sz 分のメモリをヒープ領域から確保する。
POINT
デバッグ用に malloc をラップする。
#ifdef _DEBUG
# define MALLOC( s ) malloc( s, __FILE__, __LINE__ )
#else
# define MALLOC( s ) malloc( s )
#endif
void *p = MALLOC( 128 );
■ IO
■ printf
SYNTAX
%[フラグ][最小フィールド幅][.精度][長さ修飾子]変換指定子
RET
出力した文字数
符号指定.
+ : [ %+f ] : 常に符号表示
長さ修飾子
l : [ %lb ], :
変換修飾子
d : [ %d ] : 10 進整数
u : [ %u ] : 10 進符号なし整数
x : [ %x ] : 16 進符号なし整数
s : [ %s ] : 文字列
p : [ %p ] : Pointer の値
f : [ %f ] : 小数点形式 浮動小数
e : [ %e ] : 指数形式 浮動小数
指定子 対応する型
%c char 1文字を出力 "%c"
%s char 文字列を出力 "%8s", "%-10s"
%d int, short 整数を10進で出力 "%-2d","%03d"
%u unsigned int,
unsigned short 符号なし整数を10進で出力 "%2u","%02u"
%o int, short,
unsigned int,
unsigned short 整数を8進で出力 "%06o","%03o"
%x int, short,
unsigned int,
unsigned short 整数を16進で出力 "%04x"
%f float 実数を出力 "%5.2f"
%e float 実数を指数表示で出力 "%5.3e"
%g float 実数を最適な形式で出力 "%g"
%ld long 倍精度整数を10進で出力 "%-10ld"
%lu unsigned long 符号なし倍精度整数を10進で出力 "%10lu"
%lo long, unsigned long 倍精度整数を8進で出力 "%12lo"
%lx long, unsigned long 倍精度整数を16進で出力 "%08lx"
%lf double 倍精度実数を出力 "%8.3lf"
精度
浮動小数の小数の桁数を指定する。
char *p
// 0xaabbccdd;
printf( "%#02x ", p[i] );
// AABBCCDD;
printf( "%#02X ", p[i] );
int i = 10;
[ %04d ] : 桁数表示
WARNING
最小フィールド幅は最小の幅を指定するだけ。
幅よりも大きい値がくると幅数がふえる
int i = 2;
// " 2 2"
printf( "%2d%2d", i );
i = 123;
// "123123"
printf( "%2d%2d", i );
std::cout を利用すれば format 演算子は必要はない。
#include< iostream>
std::cout < < i < " " < < f < < " " p < < endl;
assert( !printf("name: %s", s.c_str()) && i != N );
"r", "rb" を指定するのは [\n] がきたときに MS 用に
\r\n と変換するため ( これだけの違い )
■ sprintf
SYNTAX
int sprintf(
char *str,
const char *format,
...
);
RET
OK : strに格納した文字数(最後の'\0'は除く)
DESC
書式 format にしたがい
printf 関数と同様の変換をした出力を文字列 str にセットする。
WARNING
%X の場合は
整数を引数とするため
char -> int
-1 -> 0xFFFF FFFF
// 4 Byte 整数に CAST される
char c;
sprintf( buf, "%X", c );
WARNING
format によって簡単にバッファーオーバーランを起こすため
書き込み文字列指定 sprintf を使うこと。
REFERENCE _snprintf_s
char buf[256];
void log( const char *msg ) {
sprintf( buf, "%s", msg );
}
■ vsnprintf_s(_vsnprintf_s)
SYNTAX
int vsnprintf_s(
char *buf,
size_t sz, // バッファサイズ
size_t count, // 書き込む文字数 ( 最後の \0 を含めない )
const char *format,
va_list argptr
);
RET
N : 書かれた文字数 ( \0 を含めない )
-1 : エラー または count 以上の文字が切り捨てられた。
DESC
vsprintf のセキュア版。
C4996 が出る場合は これを利用する。
POINT
vsnprintf_s と _vsnprintf_s は同じ。 ( _vsnprintf_s は下位互換のため残している )
char buf[ 256 ];
_vsnprintf_s( buf, sizeof(buf), sizeof(buf)-1, "test %s", __FILE__ );
■ vsnprintf
SYNTAX
int vsnprintf(
char * restrict s,
size_t n,
const char * restrict format,
va_list arg
);
■ vsprintf(vswprintf)
DESC
可変引数リストをもつ sprintf
printf のカスタマイズ版をつくる。
void print( const char *form, ... )
{
char buf[1024];
va_list arg;
va_start( arg, form );
vsprintf( buf, form, arg );
va_end(arg);
printf ( "INFO: %s\n", buf );
}
void main()
{
print( "result = %d", 777 );
print( "msg = %s", "test" );
}
■ vprintf
SYNTAX
vprintf(
const char *format, // 書式文字列
... // 可変引数
);
DESC
可変引数と書式文字列従って標準出力へ書き出す
RET
N : 出力した byte 数
< 0: 出力した byte 数
void p(const char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
vprintf(fmt, arg);
va_end(arg);
char buf[256];
gets(buf);
}
■ fflush
SYNTAX
fflush
DESC
バッファリングされた出力を強制的に出力する
■ fopen
SYNTAX
FILE *fopen(const char *FILE, const char *MODE);
DESC
■ fseek
SYNTAX
int fseek(
FILE *FP, // File Pointer
long OFFSET, // 検索位置からの offset
int WHENCE // 検索開始位置
)
DESC
FILE Pointer の読み込み位置を移動する
FILE *fp = fopen( "test.txt", "r" );
// 先頭 から offset 0
fseek( fp, 0, SEEK_SET );
long s = ftell( fp );
// 末尾 から offset 0
fseek( fp, 0, SEEK_END );
long e = ftell( fp );
// file size を取得
int sz = e - s;
printf( "file size %d\n", sz );
// データを読む場合は先頭にもどすこと
fseek( fp, 0, SEEK_SET );
char *buf = (char*)malloc( sz );
fread( buf, sz, 1, fp );
■ ftell
SYNTAX
long ftell(FILE *FP);
DESC
File Pointer の位置を返す
// FileSize をとる
fseek(fp, 0, SEEK_END);
uint32_t e = ftell(fp);
printf("file pos = %ld\n", e );
fseek(fp, 0, SEEK_SET);
int s = ftell(fp);
printf("file pos = %ld\n", s );
■ rand
SYNTAX
int rand()
DESC
0 - RAND_MAX の値を返す。
WARNING
あまり random でないので利用しないこと。
include< stdlib.h>
int r = rand();
■ scanf
SYNTAX
int scanf( const char *fmt, ... );
// space, tab などの 空白文字は 無視される
// shell> 25 DEC 1111
scanf( "%d %s %d", &day, month, %year );
WARNING
// 値を格納できるように Pointer でないといけない
BAD
// 領域外の Memory にアクセスされてしまう
int n;
scanf( "%d", n );
OK
scanf( "%d", &n );
■ getchar
SYNTAX
int getchar()
DESC
STDIN から 1文字の入力をうける
WARNING
int 型だが, 入力ストリームからうけるサイズは 1 byte
#define getchar( ) getc(stdin)
■ gets
SYNTAX
char *gets(
char *buf
);
DESC
標準入力から 改行コード \n があるまで buf へ読み取る。
■ fgets
SYNTAX
char *fgets(
char *buf,
int n,
FILE *fp
);
DESC
行単位で file から n-1 サイズ分の文字列を buf へ読む。
読み込む文字は \n も含まれる。
最後に '\0' が追加される。
\n が途中できた場合, その時点で終了。
RET
!0: 読み込んだ領域の先頭アドレス
vector< string> readText( const char *path )
{
vector< string> a;
char buf[1024];
FILE *fp = fopen( path, "r" );
while( fgets( buf, sizeof(buf), fp ) ) {
// [\n] 削除
buf[ strlen(buf) - 1 ] = '\0';
a.push_back( buf );
}
fclose(fp);
return a;
}
標準入力も FILE *なので fgets から読むことができる。
{
char buf[1024];
while( fgets( buf, sizeof(buf), stdin ) ) {
// [\n] 削除
buf[ strlen(buf) - 1 ] = '\0';
printf( "stdin input [%s]\n", buf );
}
}
指定したディレクトリ内のファイルをアーカイブする。
find -name "*.bmp" | xargs cygpath -am | ./archive.exe
■ putchar
SYNTAX
int putchar(int c);
RET
DESC
stdout へ 文字 c を 出力する
#define putchar(c) __sputc(c, stdout)
nm /lib/libc.a
./main
# Pipe
echo abcdef | ./main
int main() {
int c;
// stdin から 1 文字取得 -> keyboard なら block される
c = getchar();
// stdout への Buffer を 0 にすると, すぐに出力される
#if 0
setbuf( stdout, NULL );
#endif
for (c = 'A'; c < = 'Z'; c++) {
// Buffering されるため, すぐには画面には表示されない
putchar(c);
}
sleep( 3 );
// ここで出力
printf("finish\n");
}
■ putc
SYNTAX
int putc(int CH, FILE *fp);
DESC
fp が指すストリームへ1文字を出力するマクロ。
CH が指すデータは int 型から unsigned char 型へ変換後に出力される。
■ puts
SYNTAX
void puts();
DESC
stdout へ指定文字列を出力するマクロ。
fputs( str, stdout); // == printf( str );
WARNING
実装によっては文字数制限あり. 360 ( 256 しか入力できない. )
■ math
#include< math.h>
#include< stdlib.h>
■ abs
SYNTAX
int abs(int i);
DESC
i の絶対値をかえす
■ fabs
SYNTAX
double fabs(double d);
DESC
d の絶対値をかえす
■ fabsf
SYNTAX
float fabs(float f);
DESC
f の絶対値をかえす
ANSI C 準拠ではないが、 VisualC++, gcc コンパイラでは使えそう。
float f = -0.1f;
f = fabsf( f );
printf( "ret %f\n", f );
■ stdlib
■ atoi
SYNTAX
int atoi( const char *)
DESC
文字列を 数値に変換
int i;
// 10
i = atoi( "10" );
// 10
i = atoi( "10.1" );
// 数値に変換できない場合は 0
// RET
// 0
i = atoi( "aaa" );
■ abort
SYNTAX
void abort()
DESC
プログラムを不正終了する。
C++ 例外の terminate() からも呼ばれる。
■ getenv
DESC
C 標準関数. 環境変数の値を取得
SYNTAX
// const char * でない点に注意
char *p = getenv( ENV );
char *p = getenv( env ); // 大文字小文字 同じ結果 ?
RET
OK : ptr
FAIL: NULL
ENV は大文字で統一
■ qsort
SYNTAX
void qsort(
void *data, // 並び替えるデータのアドレス
size_t nr, // 要素数
size_t size, // 各要素の size
int(*compar)(const void *a, const void *b) // 比較関数
);
DESC
nr 個の大きさ size の要素をもつ配列を並べ変える。
昇順に並べるには比較関数は次の規約に従うようにする。
比較関数
int(*compar)(const void *a, const void *b)
a > b : return positive
a < b : return negative
a == b : return 0
WARNING
二つの要素の比較結果が等しいとき
並べ変えた後の二つの順序は規定されていない
int cmp( const void *_a, const void *_b ) {
int *a = (int *)_a;
int *b = (int *)_b;
if ( *a > *b ) return 1;
else if ( *a < *b ) return -1;
return 0;
}
int a[] = { 1, 4, 9, 2, 5 };
size_t nr = sizeof(a)/sizeof(int);
// 1 2 4 5 9
qsort( a, nr, sizeof(int), cmp );
■ bsearch
SYNTAX
void *bsearch(
const void *key, // 検索する値
const *void // 配列の先頭アドレス
size_t nr, // 要素数
size_t size, // 要素ごとのサイズ
int (*COMPAR)(const void *, const void *)
);
DESC
ソートすみの配列から、key と同じ値をもつ要素を検索してそのアドレスを返す。
比較関数
int(*compar)(const void *a, const void *b)
a > b : return positive
a < b : return negative
a == b : return 0
int cmp( const void *_a, const void *_b ) {
int *a = (int *)_a;
int *b = (int *)_b;
if ( *a > *b ) return 1;
else if ( *a < *b ) return -1;
return 0;
}
int a[] = { 1, 4, 9, 2, 5 };
size_t nr = sizeof(a)/sizeof(int);
// 1 2 4 5 9
bsearch( 1, a, nr, sizeof(int), cmp );
■ ctype
■ isspace
SYNTAX
int isspace(
int c
);
DESC
c が空白文字の場合、0 以外の値を返す
RET
!0 : c が空白文字 (0x09 〜 0x0D || 0x20)
POINT
結果は現在のロケールの LC_CTYPE カテゴリの設定によって異なる
POINT
CRT デバッグ ライブラリを使用すると
CRT アサートを表示する
CRT デバッグ ライブラリを使用すると
isspace はパラメータを配列のインデックスとして使用し
■ ispunct
SYNTAX
int ispunct(
int c
);
// Locale を指定する Version
int _ispunct_l(
int c,
_locale_t locale
);
DESC
文字が区切り文字かどうかを判定
RET
!0 : c が特定の区切り文字の表現
POINT
区切り文字 とは 印字可能な文字 から 次の範囲ではないもの
印字可能な文字とは
( 空白文字 || isalnum(c) != 0 ) でない文字のこと
■ isalpha
SYNTAX
int isalpha(
int c
);
DESC
c が英字の表現の場合
これらの各ルーチンは 0 以外の値を返す
RET
!0 : c が A 〜 Z、|| a 〜 z
■ isalnum
SYNTAX
int isalnum(
int c
);
DESC
c が英数字のいずれかである場合、0 以外の値を返す
c が isalpha || isdigit の値が 0 以外になる場合
( c が A 〜 Z、a 〜 z、|| 0 〜 9 )
POINT
isalnum の結果は
現在のロケールの LC_CTYPE カテゴリの設定によって異なる
iswalnum はテスト条件の結果はロケールとは無関係
POINT
UNICODE は Locale を統一しているということ
■ isleadbyte
SYNTAX
int isleadbyte(
int c
);
RET
!0 : テスト合格
0 : テスト不合格
"C" ロケール, シングルバイト文字セット (SBCS: single-byte character set) ロケールでは
isleadbyte は常に 0 を返す
■ setlocale
SYNTAX
char *setlocale(
int category, // 設定する locale のカテゴリ
const char *locale // Locale 名
);
wchar_t *_wsetlocale(
int category,
const wchar_t *locale
);
DEP
< locale.h>
REF
v=VS.71.aspx
DESC
RET
NULL : 設定が無効
!NULL : 設定された Locale 名への Pointer
// すべての Category を "english" に
setlocale( LC_ALL, "English" );
POINT
Category の種類
LC_CTYPE
文字処理関数 (isdigit、isxdigit、mbstowcs、mbtowc の各関数は除く)。
POINT
Localeとは
国や言語にあわせた環境設定のこと
この地域性に合わせてプログラムのさまざまな側面をカスタマイズできる
ロケールのカテゴリは
日付,通貨値の表示形式など
1 つの言語で複数の形式がサポートされている場合
その言語の既定文字列を locale に設定したときに
setlocale 関数が戻す値をチェックし
どの形式が有効になっているのか確認する必要がある
たとえば、
"chinese" を指定すると
chinese-simplified || chinese-traditional のいずれかの値が返る
POINT
引数 locale は、ロケール名を指定する文字列へのポインタです
locale で空の文字列を指すと
そのロケールは実装で定義されているネイティブ環境になる
setlocale( LC_CTYPE, "" ); // 自分の環境では 日本語 ( SJIS )の isleadbyte() が機能した
値 C は、C に関する ANSI 規格に最低限準拠した環境を指定します
C ロケールでは
char 型のデータがすべて 1 バイトで表現され
値が常に 256 未満と想定される
C ロケールは、Microsoft Visual C++ Version 1.00、Microsoft C &&
C++ の旧バージョンでサポートされている唯一のロケールです
Microsoft Visual C++ では、「言語および国/地域識別文字列」で示す
すべてのロケールをサポートしています
プログラムの起動時に
次のステートメントと同等の処理が実行される
setlocale( LC_ALL, "C" );
■ math
■ atan
SYNTAX
float atanf( float )
double atan ( double )
DESC
tangent の値から [ -PI/2 : PI /2 ] の範囲の radian を返す
float rad = atanf( v.z / v.x )
■ system
■ exit
SYNTAX
void exit( int )
DESC
プログラムを終了する。
■ atexit
DESC
exit() の前にコールされるコールバックを指定する。
int atexit( void (*fn)() );
■ abort
SYNTAX
void abort()
DESC
プログラムをを異常終了させる。
SIGABRT 例外を発生させる。
■ atof
SYNTAX
double atof( const char *s )
DESC
文字列表現の数値を double 型に変換する。
POINT
strtod( s, (char**)NULL )と同じ
■ system
SYNTAX
int system( char *cmd );
RET
シェルが返す終了コード。
DEP
< stdlib.h>
DESC
Execute command string
別のコマンド(Program)を実行する
OS の Shell( Windows なら cmd.exe )に引数の文字列をわたす
こうしているのと同じ
:: こういう呼び出しをすると Block される
cmd> xxx.bat
:: これは Block されない
cmd> start xxx.bat
起動した Program が終了するまでまつ
( 正しくは cmd.exe が終了するまでまつ )
WARNING
Windows Application から実行すると, ConsoleWindow が表示される。
こうすると とりあえず できる
system( "start /min xxx.bat");
ProcessTree 的にはこうなる
// ie. system() は cmd.exe を起動する < -> cmd /c "xxx" と同じ
xxx.exe
cmd.exe // system()
start command を使うとこうなる
■ 非.ANSI C
■ sprintf_s
SYNTAX
int sprintf_s(
char *buffer,
size_t sz, // バッファサイズ
const char *format
[, argument] ...
);
RET
-1 : 失敗
DESC
VS2005 から 文字列操作関数の使用に警告がでる
文字数を指定するのは 責任はあなたにありますよ ! ということ
sprintf_s は
出力バッファのサイズを受け取り、
バッファが小さすぎて出力テキストを格納できないなら
バッファは空文字列に設定され無効なパラメータハンドラが呼ばれる。
snprintf とは異なり sprintf_s() は必ずバッファは null で終わる。
sprintf_s と sprintf の違い
sprintf_s は書式指定文字列の有効な書式指定文字をチェックするが
sprintf は書式指定文字列またはバッファが NULL ポインタかどうかのみをチェックする。
WARNING
"test" < -> "test\0"と同じ 5 byte かきこまれる
4 文字だと思うと大怪我をする
// 次はおちる
// Debug では : Assert: Buf Too Small となる
// Release では : おちる
sprintf_s( buf, 1, "" );
警告を消すには
#define _CRT_SECURE_NO_DEPRECATE 1
#pragma WARNING(disable:4996)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
WARNING
null terminate されないので _snprintf() は禁止 !
{
// Buffer Size = 8
char buf[] = "1234567";
int ret = _snprintf_s( buf, sizeof(buf), sizeof(buf)-1, "foo" );
int ret = _snprintf_s( buf, sizeof(buf), _TRUNCATE, "foo" );
assert( ret != -1, "fail" );
if ( ret == -1 ) {
printf( "切り捨てられた\n" );
}
else {
printf( "%d + 1 文字かきこみました\n", ret );
}
}
■ _snprintf_s
SYNTAX
int _snprintf_s(
char *buf, // 書きこむバッファへのポインタ
size_t szBuffer, // バッファサイズ
size_t count, // 書く文字数
const char *format
[, argument] ...
);
RET
-1 : バッファサイズが足りずに切り捨てられた
N : 書いたバイト数 ( null を除く )
DESC
指定したバッファへ, count バイト数の文字 + NULL 文字を書き込む
POINT
Secure といっても 引数の指定を間違えるとおちる
意味は
szBuffer の 大きさの Buffer へ
カウント数 + [\0] バイトを書いてね ! という意味
だから 次のように言うと , 馬鹿正直に実行しておちる
適切な指示をしないと ダメということ
{
// 8 byte の大きさ
char buf[] = "01234567";
// + null だけ overrun する
// ERROR
_snprintf_s( buf, sizeof( buf ), sizeof(buf), "01234567" );
_TRUNCATE( イッパイ まで ) を利用すれば, バッファオーバーランをしない
// n = -1, "0123456"
char buf[8];
int n = _snprintf_s( buf, sizeof( buf ), _TRUNCATE, "01234567" );
以下のようにするのが正しい。null terminate してくれるのを忘れずに。
_snprintf_s( buf, sizeof( buf ), sizeof(buf)-1, "abcdefgh" );
■ _popen._pclose
SYNTAX
DESC
System 関数に Pipe 機能を追加した内容
shell に Command を実行させて, Read, Write としての Pipe を取得する
WARNING
ConsoleWindow は表示されてしまう
表示しないためには
int test() {
FILE *in_pipe;
// 読み込み用バッファ
const int SZ = 256;
char buf[SZ + 1];
int nr;
memset(buf,'\0',sizeof(buf));
/*
POINT
stdout から取得するには 読み込み用の PIPE を開く
stdin へ書き込むには 書き込み用パイプを開く
*/
// hostname の結果をうけとる
in_pipe = _popen("hostname","r");
/*
処理は通常のファイルストリームと同じ
*/
if(in_pipe != NULL){
nr = fread(buf,sizeof(char),SZ,in_pipe);
while ( nr > 0 ) {
puts( buf );
nr = fread(buf,sizeof(char),SZ,in_pipe);
}
/* 閉じる */
_pclose(in_pipe);
return 1;
}
return 0;
}
■ sizeof
DESC
object の memory 占有領域を調べる
object の size なのでポインタを指定するとポインタオブジェクトのサイズを返す
void func( char *buf ) {
// ERROR: sizeof( buf ) == 4
memset( buf, sizeof(buf), 0 );
}
TIP
COUNTOF macro で 宣言が可視の配列( pointer でない )のサイズを取得可能
count of では ptr 配列objsize / 1ptr 配列objsize として計算
WARNING
wptr 配列では sizeof( ptr[0] ) = 4;
int data[10]; // = 40
int *p
p = data;
sizeof( p ) = 4 // pointer object size == 4
sizeof( *p ) = 4 // p がさす obj という解釈にならない
■ unicode
lstrcpy( LPTSTR str1, LPCTSTR lpString2 )