MUSASHI C source: xtselrand.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <stdlib.h>
0009: #include <limits.h>
0010:
0011: #include <xtselrandHelp.h>
0012: struct mssComHelp comHelp={
0013: "xtselrand", /* コマンド名 */
0014: "1.0", /* バージョン */
0015: HELPT, /* コマンドタイトル */
0016: HELPS, /* 要約 */
0017: HELPE, /* 利用例 */
0018: HELPR, /* 参照コマンド */
0019: HELPA, /* 作者情報 */
0020: HELPB, /* バグレポート情報 */
0021: HELPH /* ホームページ */
0022: };
0023:
0024: extern struct mssGlobalVariables mssGV;
0025:
0026: int main(int argc, char *argv[]){
0027: /*============================================================================*/
0028: /* オプション宣言&定義 */
0029: /*============================================================================*/
0030: /*----------------------------------------------------------------------------*/
0031: /* キー項目 */
0032: /*----------------------------------------------------------------------------*/
0033: MssOptKEY optKEY={
0034: OKEY, /* オプションタイプ */
0035: "k", /* キーワード(複数文字は不可) */
0036: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0037: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0038: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0039: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0040: /* 1:全ての行を異るキー値として扱う */
0041: /* 2:全ての行を同じキー値として扱う) */
0042: KEYT, /* このオプションのタイトル(Helpで表示) */
0043: KEYC /* このオプションのコメント(Helpで表示) */
0044: };
0045:
0046: /*----------------------------------------------------------------------------*/
0047: /* 選択件数 */
0048: /*----------------------------------------------------------------------------*/
0049: MssOptINT optCNT={
0050: OINT, /* オプションタイプ */
0051: "c", /* キーワード(複数文字は不可) */
0052: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0053: 1, /* デフォルト(数値として指定) */
0054: 1, /* 最小値 */
0055: INT_MAX,/* 最大値 */
0056: CNTT, /* このオプションのタイトル(Helpで表示) */
0057: CNTC /* このオプションのコメント(Helpで表示) */
0058: };
0059:
0060: /*----------------------------------------------------------------------------*/
0061: /* 選択件数(割合) */
0062: /*----------------------------------------------------------------------------*/
0063: MssOptDBL optPCT={
0064: ODBL, /* オプションタイプ */
0065: "p", /* キーワード(複数文字は不可) */
0066: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0067: 0, /* デフォルト(数値として指定) */
0068: 0, /* 最小値 */
0069: 100, /* 最大値 */
0070: PCTT, /* このオプションのタイトル(Helpで表示) */
0071: PCTC /* このオプションのコメント(Helpで表示) */
0072: };
0073:
0074: /*----------------------------------------------------------------------------*/
0075: /* 乱数の種 */
0076: /*----------------------------------------------------------------------------*/
0077: MssOptINT optSED={
0078: OINT, /* オプションタイプ */
0079: "S", /* キーワード(複数文字は不可) */
0080: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0081: -1, /* デフォルト(数値として指定) */
0082: -1, /* 最小値 */
0083: INT_MAX,/* 最大値 */
0084: SEDT, /* このオプションのタイトル(Helpで表示) */
0085: SEDC /* このオプションのコメント(Helpで表示) */
0086: };
0087:
0088: /*----------------------------------------------------------------------------*/
0089: /* 条件不一致出力ファイル */
0090: /*----------------------------------------------------------------------------*/
0091: MssOptOTF optNOF={
0092: OOTF, /* オプションタイプ */
0093: "u", /* キーワード(複数文字は不可) */
0094: 0, /* 0:オプション, 1:必須 */
0095: NOFT, /* このオプションのタイトル(Helpで表示) */
0096: NOFC /* このオプションのコメント(Helpで表示) */
0097: };
0098:
0099: /*----------------------------------------------------------------------------*/
0100: /* シーケンシャル処理 */
0101: /*----------------------------------------------------------------------------*/
0102: MssOptFLG optSEQ={
0103: OFLG, /* オプションタイプ */
0104: "q", /* キーワード(複数文字は不可) */
0105: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0106: SEQT, /* このオプションのタイトル(Helpで表示) */
0107: SEQC /* このオプションのコメント(Helpで表示) */
0108: };
0109:
0110: /*----------------------------------------------------------------------------*/
0111: /* 入力ファイル */
0112: /*----------------------------------------------------------------------------*/
0113: MssOptINF optINF={
0114: OINF, /* オプションタイプ */
0115: "i", /* キーワード(複数文字は不可) */
0116: 0, /* 0:オプション, 1:必須 */
0117: 1, /* 指定可能の最大ファイル数 */
0118: 0, /*1:file not foundのエラーで終了しない 0:する */
0119: INFT, /* このオプションのタイトル(Helpで表示) */
0120: INFC /* このオプションのコメント(Helpで表示) */
0121: };
0122:
0123: /*----------------------------------------------------------------------------*/
0124: /* 出力ファイル */
0125: /*----------------------------------------------------------------------------*/
0126: MssOptOTF optOTF={
0127: OOTF, /* オプションタイプ */
0128: "o", /* キーワード(複数文字は不可) */
0129: 0, /* 0:オプション, 1:必須 */
0130: OTFT, /* このオプションのタイトル(Helpで表示) */
0131: OTFC /* このオプションのコメント(Helpで表示) */
0132: };
0133:
0134: /*----------------------------------------------------------------------------*/
0135: /* 圧縮出力 */
0136: /*----------------------------------------------------------------------------*/
0137: MssOptFLG optZIP={
0138: OFLG, /* オプションタイプ */
0139: "z", /* キーワード(複数文字は不可) */
0140: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0141: ZIPT, /* このオプションのタイトル(Helpで表示) */
0142: ZIPC /* このオプションのコメント(Helpで表示) */
0143: };
0144:
0145: /*----------------------------------------------------------------------------*/
0146: /* plain text */
0147: /*----------------------------------------------------------------------------*/
0148: MssOptFLG optTXT={
0149: OFLG, /* オプションタイプ */
0150: "t", /* キーワード(複数文字は不可) */
0151: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0152: TXTT, /* このオプションのタイトル(Helpで表示) */
0153: TXTC /* このオプションのコメント(Helpで表示) */
0154: };
0155:
0156:
0157: /*----------------------------------------------------------------------------*/
0158: /* ワークファイル用ディレクトリ名 */
0159: /*----------------------------------------------------------------------------*/
0160: MssOptSTR optTMP={
0161: OSTR, /* オプションタイプ */
0162: "T", /* キーワード(複数文字は不可) */
0163: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0164: MssTempDir, /* デフォルト */
0165: 1, /* 文字列の最小長 */
0166: MssFileNameMaxLen, /* 文字列の最大長 */
0167: TMPT, /* このオプションのタイトル(Helpで表示) */
0168: TMPC /* このオプションのコメント(Helpで表示) */
0169: };
0170:
0171: /*----------------------------------------------------------------------------*/
0172: /* オプションをまとめる */
0173: /*----------------------------------------------------------------------------*/
0174: void *opt[]={&optKEY,&optCNT,&optPCT,&optSED,&optNOF,&optSEQ,
0175: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0176:
0177: /*============================================================================*/
0178: /* 変数宣言&定義 */
0179: /*============================================================================*/
0180: struct mssHeader *hdi; /* 入力ファイル用<head>タグ格納構造体 */
0181: struct mssHeader *hdo; /* 出力ファイル用<head>タグ格納構造体 */
0182: struct mssFPR *fpr; /* 入力ファイル構造体 */
0183: struct mssFPW *fpw; /* 出力ファイル構造体 */
0184: struct mssFPW *fpw2; /* 条件不一致出力ファイル構造体 */
0185: struct mssFldRecKey *frk=NULL; /* 項目-キーバッファ構造体 */
0186: struct mssFields *sf; /* ソート項目構造体 */
0187: int sorted; /* ソート済チェック用 */
0188:
0189: int select;
0190: int remaining;
0191: int r; /*元データのwhile内行数カウンタ*/
0192:
0193: /*----------------------------------------------------------------------------*/
0194: /* 前処理 */
0195: /*----------------------------------------------------------------------------*/
0196: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0197: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0198: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0199: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0200: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0201: mssSetOptKey(&optKEY, hdi); /* オプション項目をヘッダー項目に関連づけ*/
0202:
0203: /*ソート項目の作成*/
0204: sf=mssInitFields();
0205: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0206: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0207: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0208:
0209: /*mssShowFields(sf);*/
0210: /*mssShowOption(opt);*/
0211: /*mssShowHeader(hdi);*/
0212:
0213: if(optCNT.set + optPCT.set != 1){
0214: mssShowErrMsg("must specify either -c or -p");
0215: mssEnd(mssErrorNoDefault);
0216: }
0217:
0218: /*----------------------------------------------------------------------------*/
0219: /*出力ヘッダーの作成と出力 */
0220: /*----------------------------------------------------------------------------*/
0221: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0222: hdo=mssInitCpyHeader(hdi);
0223:
0224: /*入力ヘッダの全項目を追加*/
0225: mssAddFieldsByFields(hdo->flds,hdi->flds);
0226:
0227: /*ソートする必要があるならばsfのソート情報を反映*/
0228: if(!optSEQ.set && !sorted){
0229: mssSetFieldsSort(hdo->flds,sf);
0230: }
0231:
0232: /*標準出力オープン+ヘッダーの出力*/
0233: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0234: mssWriteHeader(hdo, fpw);
0235:
0236:
0237: /*条件不一致出力オープン+ヘッダーの出力*/
0238: if(optNOF.set){
0239: fpw2=mssOpenFPW(optNOF.str,optZIP.set,0);
0240: mssWriteHeader(hdo, fpw2);
0241: }else{
0242: fpw2=NULL;
0243: }
0244:
0245: /*----------------------------------------------------------------------------*/
0246: /*メインルーチン */
0247: /*----------------------------------------------------------------------------*/
0248: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0249: if(!optSEQ.set && !sorted)
0250: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0251:
0252: mssInitRand(optSED.val); /*乱数初期化*/
0253:
0254: /*FRK構造体の初期化*/
0255: frk=mssInitFRK(hdi->flds->cnt, &optKEY, optTMP.str);
0256:
0257: while(1){
0258: /*データ読み込み*/
0259: if(EOF==mssReadFRK(fpr,frk)) break;
0260:
0261: /*サンプリング*/
0262: remaining=frk->keyRecCnt;
0263: if(optCNT.set)select=optCNT.val;
0264: else select=(int)((optPCT.val/(double)100)*(double)frk->keyRecCnt);
0265: if(select>frk->keyRecCnt) select=frk->keyRecCnt;
0266: r=0;
0267: while( EOF != mssReadFldRecFRK(frk) ){
0268: mssGV.inCnt++;
0269: if( (rand()%remaining) < select ){
0270: mssWriteFld(frk->pnt,frk->fldCnt,"\n",fpw);
0271: mssGV.outCnt++;
0272: select--;
0273: }else{
0274: if(optNOF.set){
0275: mssWriteFld(frk->pnt,frk->fldCnt,"\n",fpw2);
0276: }
0277: }
0278: r++;
0279: remaining--;
0280: }
0281: }
0282: mssFreeFRK(frk);
0283:
0284: /*----------------------------------------------------------------------------*/
0285: /*フッター出力&終了処理 */
0286: /*----------------------------------------------------------------------------*/
0287: /*printf("allocCnt=%d\n",getAllocCnt());*/
0288: mssWriteFooter(fpw); /*フッターの出力 */
0289: mssWriteFooter(fpw2); /*フッターの出力 */
0290: mssCloseFPW(fpw); /*出力ファイルのクローズ */
0291: mssCloseFPW(fpw2); /*出力ファイルのクローズ */
0292: mssCloseFPR(fpr); /*入力ファイルのクローズ */
0293: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0294: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0295: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0296: mssFreeOption(opt); /* オプション領域開放 */
0297: mssShowEndMsg(); /* 完了メッセージ */
0298: mssEnd(mssExitSuccess); /* 終了 */
0299: return(0); /* to avoid warning message */
0300: }