2013年7月 初版
会場: 天文データセンター
#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