2013年7月 初版
2015年11月 第2版
会場: 天文データセンター
#include <stdio.h> static void display_2d_array( double *arr_2d[], int n_x, int n_y ) { int i; // 2次元配列としてアクセス for ( i=0 ; i < n_y ; i++ ) { /* 縦方向のループ */ int j; for ( j=0 ; j < n_x ; j++ ) { /* 横方向のループ */ printf("[%g]",arr_2d[i][j]); } printf("\n"); } return; } int main() { double array[] = {10.0, 11.1, 12.2, 13.3, 20.0, 21.1, 22.2, 23.3}; /* この配列を 4x2 として使う */ double *p[2]; /* ポインタ配列 */ p[0] = &array[0]; p[1] = &array[4]; display_2d_array(p,4,2); return 0; }結果:
[10][11.1][12.2][13.3] [20][21.1][22.2][23.3]
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <sys/types.h> /** * @brief 1つの文字列をスキャンし,デリミタで要素へ分割するための情報を取得 * @param str スキャン対象の文字列 * @param delim デリミタ(文字セット) * @param begin 各要素文字列の先頭位置 (返り値) * @param length 各要素文字列の長さ (返り値) * @param max_n begin[], length[] のサイズ * @return 要素の個数 */ static size_t sscan_str( const char *str, const char *delim, size_t begin[], size_t length[], size_t max_n ) { size_t ix = 0; /* 文字列のパース位置 */ size_t n_elem = 0; /* 要素の個数 */ size_t spn; /* 最初のデリミタを飛ばす */ spn = strspn(str + ix, delim); ix += spn; while ( n_elem < max_n ) { /* 要素部分 */ spn = strcspn(str + ix, delim); if ( spn == 0 ) break; /* 配列に登録 */ begin[n_elem] = ix; length[n_elem] = spn; n_elem ++; ix += spn; /* デリミタを飛ばす */ spn = strspn(str + ix, delim); if ( spn == 0 ) break; ix += spn; } return n_elem; } /** * @brief ファイルから必ず1行を読みとる.バッファサイズ以上の部分は捨てられる * @param fp ファイルハンドラ * @param str 1行分を保存するバッファ * @param size_str str[]のバッファサイズ * @return 成功した場合は str を返す<br> * EOFまたはエラーの場合 NULL */ static char *fget_str( FILE *fp, char *str, size_t size_str ) { char *ret; ret = fgets(str, size_str, fp); if ( ret != NULL ) { size_t length = strlen(str); /* バッファが足りない場合,読み飛ばす */ if ( 0 < length && str[length-1] != '\n' ) { char junk[256]; char *r; while ( (r=fgets(junk,256,fp)) != NULL ) { size_t len = strlen(junk); if ( len == 0 ) break; length += len; if ( junk[len-1] == '\n' ) break; } fprintf(stderr,"[WARNING] %s: truncated: total length = %zu\n", __FUNCTION__, length); } } return ret; } /** * @brief ファイルから1行を読みとり,デリミタで要素へ分割するための情報を取得 * @param fp ファイルハンドラ * @param str 1行分を保存するバッファ * @param size_str str[]のバッファサイズ * @param delim デリミタ(文字セット) * @param begin 各要素文字列の先頭位置 (返り値) * @param length 各要素文字列の長さ (返り値) * @param max_n begin[], length[] のサイズ * @return 成功した場合,要素の個数<br> * EOFの場合,負値 */ static ssize_t fscan_str( FILE *fp, char str[], size_t size_str, const char *delim, size_t begin[], size_t length[], size_t max_n ) { ssize_t ret = -1; char *s; s = fget_str(fp,str,size_str); if ( s != NULL ) { size_t len = strlen(str); if ( 0 < len && str[len - 1] == '\n' ) str[len - 1] = '\0'; ret = sscan_str( str, delim, begin, length, max_n ); } return ret; } /** * @brief 安全な strncpy() 関数 * @param dest コピー先文字列 * @param size_dest コピー先文字列バッファの大きさ * @param src 源泉文字列 * @param n コピーを行なう文字数 */ inline static char *safe_strncpy( char *dest, size_t size_dest, const char *src, size_t n ) { n ++; if ( n < size_dest ) size_dest = n; if ( 0 < size_dest ) { const size_t m = size_dest - 1; strncpy(dest,src,m); dest[m] = '\0'; } return dest; } int main( int argc, char *argv[] ) { int ret_status = -1; FILE *fp = NULL; if ( 1 < argc ) { const char *file = argv[1]; const size_t max_elem = 32; size_t begin[max_elem]; size_t length[max_elem]; char buf[512]; ssize_t n; /* ファイルをオープン */ fp = fopen(file, "r"); if ( fp == NULL ) { fprintf(stderr,"[ERROR] cannot open: %s\n",file); goto quit; } /* 1行ずつスキャン */ while ( 0 <= (n=fscan_str(fp,buf,512," ",begin,length,max_elem)) ) { if ( n == 3 ) { const size_t size_el = 512; char el[size_el]; double ra, dec; safe_strncpy(el,size_el, buf + begin[0], length[0]); printf("%s ",el); safe_strncpy(el,size_el, buf + begin[1], length[1]); ra = M_PI * atof(el) / 180.0; safe_strncpy(el,size_el, buf + begin[2], length[2]); dec = M_PI * atof(el) / 180.0; printf("%g %g %g\n", cos(ra)*cos(dec), sin(ra)*cos(dec), sin(dec)); } } } ret_status = 0; quit: if ( fp != NULL ) fclose(fp); return ret_status; }実行結果:
M1 0.10281 0.921371 0.374841 M2 0.802345 -0.596687 -0.0143679 M3 -0.793808 -0.379451 0.475275 M4 -0.365393 -0.816723 -0.4466