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