基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成15年 秋期 基本情報技術者 午後 問10
問10   C言語

 次の C プログラムの説明及びプログラムを読んで,設問1,2に答えよ。

〔プログラムの説明〕

 表計算ソフトなどで使用されるデータ交換処理用のプログラムである。

(1) 関数 loadcsv は,(2) に示す様式(CSV 形式と呼ぶ)のレコードを テキストファイルから読み込み,2次元配列の表に格納する。 関数 savecsv は,表内の要素を CSV 形式に戻してテキストファイルに出力する。

(2) このプログラムで扱う CSV 形式の仕様は,次のとおりである。

@ 文字列からなるデータをコンマ“,”で区切って並べたものである。

A コンマの前後には空白が許される。

B 文字列は,全体を引用符で囲んでも囲まなくてもよい。 ただし,文字列内に空白文字,コンマ“,”を含む場合には, 図1 のように文字列全体を引用符で囲む。 文字列内に引用符は含まないものとする。

C CSV 形式ファイルには,表の1行に対応するデータ群が 1レコードとして格納されている。

D レコードの終端は“ \n ”である。

Shop-A, 1, "1,000", "21,000", "3,000"
Shop-B, 2, "4,500", "15,000", "4,000"

図1 CSV 形式のデータ例(2 レコード)

(3) レコード内の文字列は,動的に確保した領域に格納し, 表の要素にはその領域へのポインタを格納する。

(4) 引用符で囲まれたデータ形式の場合は, 動的に確保した領域に前後の引用符を除いた文字列を格納する。

(5) 対応するデータがない要素には,NULL を格納する。

(6) 図1 のレコードを格納した表を図2 に示す。

図2 CSV 形式のデータを格納した表の例(2 レコード)

(7) ここで使用される文字の種類は,JIS X 0201 (7 ビット及び8ビットの情報交換用符号化文字集合)の文字とする。

(8) 表の行数及び列数の最大値は,ともに 64 とし,レコードの文字長は 255 以下とする。

(9) CSV 形式ファイル内のレコードに記述の誤りはないものとし, ファイル入出力でのエラーも発生しないものとする。

(10) 各関数の仕様は,次のとおりである。

@ 関数 loadcsv

形式: int loadcsv( char fname[], char *tbl[][TBLSZ] );

引数: fname  入力ファイル名へのポインタ

    tbl 表(2次元配列)へのポインタ(ここで,TBLSZ は,表の行数及び列数の最大値)

返却値: 表に格納したレコード数

A 関数 savecsv

形式: void savecsv( char fname[], char *tbl[][TBLSZ],
   int ln );

引数: fname  出力ファイル名へのポインタ

tbl   表(2次元配列)へのポインタ

ln    出力するレコード数

〔プログラム〕

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define  TBLSZ   64
#define  RECSZ   256
int  loadcsv( char*, char*[][TBLSZ] );
void savecsv( char*, char*[][TBLSZ], int );
int loadcsv( char fname[], char *tbl[][TBLSZ] )
{
    FILE *fp;
    char buf[RECSZ], *cp, *dp;
    int  col, row, len;
    
    for ( row = 0; row < TBLSZ; row++ ) {
        for ( col = 0; col < TBLSZ; col++ ) tbl[row][col] = NULL;
    }
    fp = fopen( fname, "r" );
    for ( row = 0; fgets( buf, RECSZ, fp ) != NULL; row++ ) {
        col = 0;      
        for ( cp = buf; *cp != '\n'; cp++ ) {
            while ( *cp == ' ' ) cp++;     /* 空白の読み飛ばし */
            if ( *cp == '\n' ) break;
            else if ( *cp == ',' ) ;  /* コンマの処理 */
            else {
                if ( *cp == '\"' ) { /* データが引用符で囲まれている場合 */
                    dp = ;
                    for ( len = 0; *cp != '\"'; len++,  );
                }
                else {
                    dp = ;
                    for ( len = 0; *cp != '\n'; len++,  )
                      if (( *cp == ' ' ) || ( *cp == ',' ) 
                        || ( *cp == '\n' )) break;
                    ;
                }
                if ( len != 0 ) { /* データが空でない場合 */
                    tbl[row][col] = malloc( len+1 );
                                  /* 動的に領域を確保 */
                    strncpy( tbl[row][col], dp, len );
                    *(tbl[row][col]+len) = '\0';
                }
            }
        }
    }
    fclose( fp );
    return row;
}
void savecsv( char fname[], char *tbl[][TBLSZ], int ln )
{
    FILE *fp;
    int   row, col, last;
    fp = fopen( fname, "w" );
    for ( row = 0; row < ln; row++ ) {
        for ( last = TBLSZ-1; last >= 0; last-- )
            if ( tbl[row][last] != NULL ) break;
        for ( col = 0; col <= last; col++ ) {
            if ( tbl[row][col] != NULL ) {
                fputs( "\"", fp );
                fputs( tbl[row][col], fp );
                fputs( "\"", fp );
            }
            if ( col < last ) fputs( ",", fp );
        }
        fputs( "\n", fp );
    }
    fclose( fp );
}

基本情報技術者試験


設問1 プログラム中の に入れる正しい答えを,解答群の中から選べ。 なお,解答は重複して選んでもよい。

a に関する解答群

ア col++    イ dp = NULL    ウ dp++

エ len++    オ tbl[row][col] = NULL

b 〜 e に関する解答群

ア cp    イ cp--    ウ cp+1    エ ++cp

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

解答 e ←クリックすると正解が表示されます

基本情報技術者試験


設問2 次の CSV 形式の2レコードを関数 loadcsv によって表に格納し, それから関数 savecsv によって CSV 形式で出力する。 出力結果の説明として適切なものを,解答群の中から選べ。

"Taro Yamada", 43, "175.5", M, "550,000"
Hanako-Yamada, 12, "156.7", F,

解答群

ア すべてのデータに対して,引用符で囲んだものをコンマで区切って出力する。 各レコードの末尾には,不要なコンマは出力されない。

"Taro Yamada","43","175.5","M","550,000"
"Hanako-Yamada","12","156.7","F"

イ すべてのデータに対して,引用符で囲んだものをコンマで区切って出力する。 出力レコードのデータ個数は最大のものにそろえられる。

"Taro Yamada","43","175.5","M","550,000"
"Hanako-Yamada","12","156.7","F",""

ウ 入力時と同じ形式で出力する。 出力レコードのデータ個数は最大のものにそろえられる。

"Taro Yamada",43,"175.5",M,"550,000"
Hanako-Yamada,12,"156.7",F,

エ 入力時と同じ形式で出力する。 レコードの末尾には,不要なコンマは出力されない。

"Taro Yamada",43,"175.5",M,"550,000"
Hanako-Yamada,12,"156.7",F
解答 ←クリックすると正解が表示されます

[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]