C言語ソースのエラーメッセージを解析しよう

このQ&Aのポイント
  • 熟練者によるC言語ソースのエラーメッセージ解説
  • error関数の意図不明な要素について解説
  • エラーメッセージを単純にファイル出力する関数
回答を見る
  • ベストアンサー

エラーメッセージコード

古いC言語ソースを解析していたのですが、よく分からないので質問させていただきます。 下記のerror関数は、エラーメッセージを単純にファイル出力するものとして使っており、中身は単純だと思っていました。しかしva_argやcase"s"~"x"など意図が良く分からないものが出てきており、ソースを読むのに熟練してる方に中身が何をしているのか分かり易く解説して頂きたいです。 void error(char *mess,...) { FILE *f2 = stdout; va_list list; int i; int k = 0; char fmt[1000] va_start(list, mess); for(i=0;i < (int)strlen(mess); i++) { if (k >0) { fmt[k++] = mess[i]; fmt[k] = 0; switch (mess[i]) { case's': fprintf(f2,fmt,va_arg(list,char *)); k=0; break; case'c': fprintf(f2,fmt,(char)va_arg(list,int)); k=0; break; case'd': case'x' fprintf(f2,fmt,(char)va_arg(list,int)); k=0; break; } if ( k >= 1000 -2) { fprintf(f2, "too long format string\n"); break; } } else if (mess[i]== '%') { k = 0; fmt[k++] = mess[i]; fmt[k] = 0; } else fprintf(f2, "%c", mess[i]); } va_end(list); exit(1); }

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

va_list 等は、可変長引数を扱うためのものです。 va_list 、 可変長引数 等で検索すると、より詳しい解説がみつかります。 例えば、 printf では、引数が1つのときもあれば、3つのときもあります printf("hello world"); /* 引数が一つ */ printf("No.%d is %f\n",i,d[i]) ; /* 引数が3つ */ こういうのが可変長引数です。 後半のループは、 配列 fmt と変数 k の内容を追い掛ければわかるかと思います。 %があったらmessからfmtにコピーを始めて、 s,d,x等があったら、fmt を書式文字列に指定して、fprintf を実行しています。そのとき、呼び出し元で指定された可変長の引数から順番に取り出して、fprintfに指定しています。 例えば error("aa%2c",'b') ; だったら a → fprintf(f2,"%c",'a') ; /* k==0だから */ a → fprintf(f2,"%c",'a') ; /* k==0だから */ % → fmt ="%" ; /*k=1に */ 2 → fmt ="%2" ; /*k=2に */ c → fmt ="%2c" ; fprintf(f2,"%2c",'b') /*k=0に */ つまりは error(msg, a0, a1, ... ) ; が { fprintf(f2, msg, a0, a1, ...) ; exit(1); } と「ほぼ同等」の意味になります。 ただ。 単純に{ fprintf(f2, msg, a0, a1, ...) ; exit(1); } とするなら、va_list をそのままfprintfに渡せる「 vfprintf 」という関数があります。 わざわざmsgを解析する必要はありません。 fprintf(f2,fmt,(char)va_arg(list,int)); の (char)va_arg(list,int) については、意図をわかりかねます。 Cの可変長引数のルールとして「int以下の整数は、intに変換される」というのがあります。  char c ='a' ;  printf("%c",c ) ; とした場合、実際には  printf("%c",(int)c ) ; となります。よって、va_argで取り出す際には va_arg(list,int) なのが正解です。 しかし、それをまたcharに戻す理由はわかりません。 fprintfも可変長引数なので  fprintf(f2,fmt,(char)va_arg(list,int)); は  fprintf(f2,fmt,(int)( (char)va_arg(list,int) ) ); と同義です。 "%c"の方はまだ「charとして扱いたい」という(無意味な)理由が考え付きますが、 "%x","%d"の方はわかりません。 「int i ; error("%d",i) と指定なっていたら、iはintではなくcharとして下位8ビットしか見ない、ということなのでしょうか。

hososugi
質問者

お礼

お返事遅くなり大変失礼しました(PCが不調で再インストールに時間がかかってました) すみません、一か所写経で間違いがあり(古いソースで紙媒体を手打ちしてました) case'd':case'x': fprintf(f2, fmt, va_arg(list,int));でした。 回答を頂いた後半の意図不明としておられた所そのもので、申し訳ありません。 丁寧な解説ありがとうございました。

関連するQ&A

  • 可変個引数を使った関数で文字の長さを知りたい

    可変個引数を使った引数を使って引数の文字列の長さを知りたいのですがどうすればいいのかわかりません。 DXライブラリを使って文字列の長さを測って文字をどこにおくのかを決めているため文字列の長さがわからないと困ってしまいます。 どのようにすれば可変個引数を使った引数の文字列の長さを測れますか? 大体以下のような感じで作っています。 void kai( int *x , int *y ); //文字列を改行する関数 int JC( unsigned char code ); //文字が1バイト文字 か 2バイト文字か判別する void mozi_show2( int x , int y , int xm , int yb , int color , int char_set , const char *s , ... ){   int i = 0;   int xs = 0 , ys = 0;   int m_color = color;   char One[ 2 ]; //1バイト文字格納用   char Two[ 3 ]; //2バイト文字格納用   const char* p;   va_list args;   va_start( args , s );   p = s;   while( *p != '\0' ){     switch( *p ){       case '%':         p++;         assert( *p != '\0' );         switch( *p ){           case 'd':             DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%d" , va_arg( args , int ) );             //purintfと使い方はほぼ同じで左から文字を表示したいX座標・文字を表示したいY座標             //文字の色・文字の書式・格納用文字列・表示したいint型の数値をあらわしています             xs += 16;             /*             xs += GetDrawFormatStringWidthToHandle( char_set , "%d" , va_arg( args , int ) );             本来ならこの関数を使って文字列の長さを計る左から             文字列の書式・格納用文字列・長さを測りたいint型文字列             これを使うと別のものを計っているみたいで文字の長さがわからない             文字の長さってどうやって計るの?             */             break;           case 'f':             DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%f" , va_arg( args , double ) );             break;           case 'c':             DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%c" , va_arg( args , char ) );             break;           case 's':             DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%s" , va_arg( args , const char* ) );             break;           case '%':             DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%%" );             xs += GetDrawStringWidthToHandle( "%" , 1 , char_set );             break;         }         p++;         break;       default:         if( JC( *p ) ){           Two[ 0 ] = *p;           Two[ 1 ] = *( p + 1 );           Two[ 2 ] = '\0';           DrawStringToHandle( x + xs , y + ys * yb , Two , m_color , char_set );           xs += GetDrawStringWidthToHandle( Two , 2 , char_set );           p += 2;         }         else{           One[ 0 ] = *p;           One[ 1 ] = '\0';           DrawStringToHandle( x + xs , y + ys * yb , One , m_color , char_set );           xs += GetDrawStringWidthToHandle( One , 1 , char_set );           p++;         }         break;     }     if( xs > xm ){       kai( &xs , &ys );     }   }   va_end( args ); } void zitu_draw( void ){   char *str = "%d個 OK";   int i = 12;   mozi_show2( 100 , 100 , 300 , 15 , red_s , MG_14_0 , str , i );   //左から 文字を表示するX座標・文字を表示するY座標・文字を改行する文字列の長さ   //改行した時のY座標の縦幅・文字色・文字の書式・表示したい文字列・%dに表示したいint型の値 }

  • C言語のコンパイル構文エラーについて

    -----一部プログラム抜粋------ int stda_set_setting(stda_file *f, uint32_t option, ...) { va_list ap; dtc_U4 input; va_start(ap, option); input = va_arg(ap, dtc_U4); va_end(ap); switch (option) { case stda_SETTING_WRITE_SIZE: f->_write_chunk_size = input; break; case stda_SETTING_VERSION: f->ver = input; break; case stda_SETTING_BYTE_ORDER: f->byte_order = input; break; } return 0; } void stda_get_setting(stda_file *f, uint32_t option, ...) { va_list ap; dtc_U4 *ret; va_start(ap, option); ret = va_arg(ap, dtc_U4*); va_end(ap); switch (option) { case stda_SETTING_WRITE_SIZE: *ret = f->_write_chunk_size; break; case stda_SETTING_VERSION: *ret = f->ver; break; case stda_SETTING_BYTE_ORDER: *ret = f->byte_order; break; } } /* * UNCOMPRESSED SUPPORT */ static int __stda_open_reg(void *data, int flags, uint32_t mode) { stda_file *stda = (stda_file*)data; /* if filename is NULL we can assume that the fd is already set ... */ if (stda->filename) { if (stda->filename[0] == '-' && stda->filename[1] == '\0') stda->fd = 0; else stda->fd = open(stda->filename, flags, mode); } return stda->fd; } -----一部プログラム抜粋------ 上記ソースにて、【f】と【stda】に 『stda_file *stda』 『Error:式にはpointer-to-struct-or-union 型が必要です』 と表示されますが、エラーメッセージで検索してもピンポイントで出てきません。 非常に初心者的な質問かもしれませんが、C言語が未経験の為、 具体的に何がいけないのかご教示頂きたく投稿させて頂きました。 以上、宜しくお願い致します。

  • 複数の戻り値

    関数にポインタを渡して、結果を格納してもらう方法で 複数の戻り値を得ようとしたのですがうまく行きません どうしたら複数戻せますか? ---ソース--- #include <stdio.h> #include <stdlib.h> void check(int a,char *b,char *c); void main(void){ int a; char *b,*c; int i; char *va[5]={"2","3"}; for(i=0;i<5;i++){ //ここ何とかなったらwhileにしとこ if(va[i]!=NULL){ a=atoi(va[i]); check(a,b,c); printf("%s%s\n",b,c); } } } void check(int a,char *b,char *c){ switch(a){ case 0: b="0:×\n"; c="0:○\n"; break; case 1: b="1:×\n"; c="1:○\n"; break; case 2: b="2:×\n"; c="2:○\n"; break; case 3: b="3:×\n"; c="3:○\n"; break; case 4: b="4:×\n"; c="4:○\n"; break; } }

  • C言語のエラー処理について

    下記のコードを作成したのですが、入力エラーの際に出力される表示が意図した input error の出力と違う形で表示されてしまい、修正方法が分からず、どなたか教えて頂けないでしょうか? ・『あ』等の整数以外の文字が入力された時 input errorinput errorinput error ・/0が入力された時 input error input error input error 「ソースコード」 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) #define MAX_ROW (1000) float calc_proc(int* n1, char op, int n2, float* ans) { switch (op) { case '+': *ans = (float)*n1 + n2; break; case '-': *ans = (float)*n1 - n2; break; case '*': *ans = (float)*n1 * n2; break; case '/': if (n2 == 0) { puts("input error"); return 1; } *ans = (float)(float)*n1 / n2; break; default: printf("input error"); return 1; break; } return 0; } int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int i; FILE* fp; char e[11]; char sin[MAX_LINE][MAX_ROW]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { scanf("%d%c%d", &num1, &op, &num2); calc_proc(&num1, op, num2, &answer); if (calc_proc(&num1, op, num2, &answer) != 0) { puts("input error"); return 1; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s", e); if (strcmp(e, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • コンパイルするとエラーに。C言語

    OSはLINUXです。GNOME 端末を使用してます。ここの関数でエラーが起きているみたいなんです。(部分的に載せてしまいましたが、それとも全体も載せた方がいいでしょうか?) void readargs(int argc, char *argv[]) { int c; int atoi(char *); while (--argc > 0 && (c = (*++argv)[0] == '-' || c == '+') { if (c == '-' && !isdigit(*(argv[0]+1))) while (c = *++argv[0]) switch (c) { case 'd': option |= DIR; break; case 'f': option |= FOLD; break; case 'n': option |= NUMERIC; break; case 'r': option |= DECR; break; default: printf("sort: illegal option %c\n", c); error("Usage: sort -dfnr [+pos1] [-pos2]"); break; } else if (c == '-') pos2 = atoi(argv[0]+1); else if ((pos1 = atoi(argv[0]+1)) < 0) error("Usage: sort -dfnr [+pos1] [-pos2]"); } if (argc || pos1 > pos2) error("Usage: sort -dfnr [+pos1] [-pos2]"); } } ちなみに、エラー内容は「case label not within a switch statement」 「break statement not within loop or switch」です。 似たような問題はできたのですが、これだけはなぜかエラーが起きてしまいました。アドバイス・回答待ってます。

  • プログラムエラー

    プログラムを実行したところ、こんなエラーが出てしまいました。 msgrcv failure: Argument list too long 実行したいプログラムは3つのプロセスがもつ数字を順番に並べる作業です。 1番目のプロセスはうまくいくのですが、2番目が上記のようなエラーがでてきてしまいます。 なぜでしょうか?? エラーで出てくるところは int main( int argc, char** argv ) { int qid; Qmsg message; long int myNo; int myProp; int data[NUM_DATA]; int isSwap = 0; int needMinSort = 0; int needMaxSort = 0; int got_data; int totalSwapNum = 0; int i,flag,m,n,l,s; if( argc != 2){ fprintf(stderr, "Usage: %s <own order(1-10)>\n", argv[0]); exit(1); } myNo = atol(argv[1]); if( myNo <= 0 || NUM_PROCESS < myNo ){ fprintf(stderr, "Illegal own order (%ld)\n", myNo); exit(1); } switch( myNo ){ case 1: myProp = LEFT_SIDE; printf("[%ld] is LEFT SIDE\n", myNo); break; case NUM_PROCESS: myProp = RIGHT_SIDE; printf("[%ld] is RIGHT SIDE\n", myNo); break; default: myProp = MIDDLE; printf("[%ld] is MIDDLE\n", myNo); } errno = 0; if( (qid = msgget((key_t)KEY_NO, 0666 | IPC_CREAT)) == -1 ){ perror("msgget failure"); exit(1); } message.msgData.status = MSG_AWAKE; switch( myProp ){ case LEFT_SIDE: sendMsgRhs( qid, myNo, message ); break; case MIDDLE: recvMsgLhs( qid, myNo, &message );         //ここでエラー if( message.msgData.status != MSG_AWAKE ){ exit(1); } sendMsgRhs( qid, myNo, message ); break; case RIGHT_SIDE: recvMsgLhs( qid, myNo, &message ); if( message.msgData.status != MSG_AWAKE ){ exit(1); } break; } } int recvMsgLhs( int qid, long int myNo, Qmsg* message ) { long int read_from = myNo; errno = 0; if(msgrcv(qid, message, sizeof(message->msgData), read_from, 0) == -1){ perror("msgrcv failure"); exit(1); } #ifdef SHOW_XFER_MESSAGE printf("Lhs[%2ld] ---> Recv ---> [myNo:%2ld] (%s)", message->type - 1, myNo, msgStr[message->msgData.status]); switch( message->msgData.status ){ case MSG_SWAP: case MSG_NEED: case MSG_SWAP_CNT: printf(" {data:%d}\n", message->msgData.data); break; default: printf("\n"); } #endif return errno; }

  • コンパイルするとエラーに。C言語(改め)

    インクルード 定義 メイン関数 エラー内容 が収まりませんでした; (長すぎてどうすればよいのやら;) int readlines(char *lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) if (nlines >= maxlines || (p = alloc(len)) == NULL) return -1; else { line[len-1] = '\0'; strcpy(p, line); lineptr[nlines++] = p; } return nlines; } char *alloc(int n) { if (allocbuf + ALLOCSIZE - allocp >= n) { allocp += n; return allocp - n; } else return 0; } void kr_qsort(char *v[], int left, int right, int (*comp)(void *, void *)) { int i, last; void swap(char *v[], int i, int j); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left+1; i <= right; i++) if ((*comp)(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); kr_qsort(v, left, last-1, comp); kr_qsort(v, last+1, right, comp); } void swap(char *v[], int i, int j) { char *temp; temp = v[i]; v[i] = v[j]; v[j] = temp; } void readargs(int argc, char *argv[]) { char c; int atoi(char *); while (--argc > 0 && (c = (*++argv)[0] == '-' || c == '+') { if (c == '-' && !isdigit(*(argv[0]+1))) while (c = *++argv[0]) switch (c) { case 'd': option |= DIR; break; case 'f': option |= FOLD; break; case 'n': option |= NUMERIC; break; case 'r': option |= DECR; break; default: printf("sort: illegal option %c\n", c); error("Usage: sort -dfnr [+pos1] [-pos2]"); break; } else if (c == '-') pos2 = atoi(argv[0]+1); else if ((pos1 = atoi(argv[0]+1)) < 0) error("Usage: sort -dfnr [+pos1] [-pos2]"); } if (argc || pos1 > pos2) error("Usage: sort -dfnr [+pos1] [-pos2]"); } } void writelines(char *lineptr[], int nlines, int order) { int i; if (order) for (i = nlines-1; i >= 0; i--) printf("%s\n", lineptr[i]); else for (i = 0; i < nlines; i++) printf("%s\n", lineptr[i]); } int charcmp(char *s, char *t) { char a, b; int i, j, endpos; int option, pos1, pos2; int fold = (option & FOLD) ? 1 : 0; int dir = (option & DIR) ? 1 : 0; i = j = pos1; if (pos2 > 0) endpos = pos2; else if ((endpos = strlen(s)) > strlen(t)) endpos = strlen(t); do { if (dir) { while (i < endpos && !isalnum(s[i]) && s[i] != ' ' && s[i] != '\0') i++; while (j < endpos && !isalnum(t[j]) && t[j] != ' ' && t[j] != '\0') j++; } if (i < endpos && j < endpos) { a = fold ? tolower(s[i]) : s[i]; i++; b = fold ? tolower(t[j]) : t[j]; j++; if (a == b && a == '\0') return 0; } } while (a == b && i < endpos && j < endpos); return a - b; } int numcmp(char *s1, char *s2) { double v1, v2; char str[MAXSTR]; substr(s1, str, MAXSTR); v1 = atof(str); substr(s2, str, MAXSTR); v2 = atof(str); if (v1 < v2) return -1; else if (v1 > v2) return 1; else return 0; } void substr(char *s, char *str, int maxstr) { int i, j, len; extern int pos1, pos2; len = strlen(s); if (pos2 > 0 && len > pos2) len = pos2; else if (pos2 > 0 && len > pos2) error("substr: string too short"); for (j = 0, i = pos1; i < len; i++, j++) str[j] = s[i]; str[j] = '\0'; } int getline (char s[], int lim) { int c, i; i = 0; while (--lim > 0 && (c=getchar()) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } void error(char *s) { printf("%s\n", s); exit(1); }

  • 重複文字を出力させない!!

    こんにちは!! ご質問させてください。 右辺値のダブルクオートくくりの 文字列をテキストから読み込みファイルに書き込む処理ですが..... うまく取れません。下記にソースコードを提示しましたので 一読の上アドバイスいただけたらと思います。 テキストファイルのないようは k="seikyo"-"himawari" k="north"+"seikyo" これを読み込んだ場合.tファイルに書き込む内容は seikyo himawari north seikyo ですが重複した場合は書き込まないようにプログラムしたつもりです。 seikyo himawari north としたいと思っています。 希望通りの形にならないので皆様どうか お力をお貸しください。よろしくお願いします。 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<syslog.h> #define MAX_REC_A 256 #define MAXFIELD 128 #define BUFFLEN 256 #define MAX 10000 #define MBF 1024 int makemoutputhrightside(); int main(int argc ,char **argv) { makemoutputhrightside(argv[1]); } /* 右辺の値をとって.tファイルに書き込む関数 */ int makemoutputhrightside(char sum[BUFFLEN]) { FILE *ft; FILE *fh; int c; char cPid[BUFFLEN]; char *p; char *q; char *str[BUFFLEN]; int flag = 0; int i = 0; int n = 0; int k; char filename[64]; char cdmy[MAX]; strcpy(filename,sum); strcat(filename,".txt"); ft = fopen(filename, "r"); fh = fopen("moutput.t", "a"); if (ft == NULL || fh == NULL) { syslog(LOG_ERR,"開けないファイルがあります。\n"); return 1; } //ファイルを1文字ずつ読み込む while ((c = fgetc(ft)) != EOF) { switch (c) { case '"': flag = 1 - flag; /*右のクオート*/ if (flag == 0) { cPid[i] = '\0'; p = strcpy(cdmy,cPid); for(k = 0;k < n;k++){ if(*str[k] != *p) continue; if(strcmp(str[k],p) == 0) break; } if(k < n) continue; q = malloc(strlen(p) + 1); strcpy(q,p); str[n] = q; fprintf(fh, "%s ",q); i = 0; } n++; break; case '\n': if (flag == 1) { cPid[i] = '\0'; fprintf(fh, "%s \n", cPid); } flag = 0; } i = 0; break; default: if (flag == 1) { cPid[i] = c; if (i < BUFFLEN - 1) { i++; } } break; } } /* ファイルの最後が改行じゃなかった場合 */ if (i>0) { cPid[i]='\0'; fprintf(fh,"%s\n",cPid); } fclose(ft); fclose(fh); return 0; }

  • プログラムを作ったのですがエラーメッセージが出ます

    原因がわかりません。他にもいくつか作ったのですが他のものはコンパイルします。 エラーメッセージ fatal error c1083 ソースファイルが開けません 因みに作ろうとしているプログラムは * ** *** **** ***** **** *** ** * を描画させるものです #include<stdio.h> main() { int i, j; int k; for(i=1; i<=9; i++){ if(i<5){ k=i; } if(i>=5){ k=10-i; } for(j=1; j<=k; j++){ printf("*"); } printf("\n"); } }

  • ファイルをオープンするときのエラー

    C言語であるファイルにある数値を100ごとに合計して,ほかのファイルに書き出す。しかし,実行するとエラーでてきます。原因はわからないです。因みに,オープンしたいファイルをほかのディレクリに置いたら,ファイルが見付かりませんとのエラーがありました、WindowsのC言語でカレントディレクトリを探すときは何の関数を使えばいいでしょうか? int main(void) { int i,k; int num; char filename[64],fileread[64],filewrite[64]; FILE *fp0,*fp1; double sum1,sum2,sum3; int *ch[3]; sum1=sum2=sum3=0.0; printf("ファイル名を入力ください!\n"); scanf("%s",filename); fprintf(stderr,"\n%s\n",filename); sprintf(fileread,"C:\\%s.txt",filename); fprintf(stderr,"%s\n",fileread); sprintf(filewrite,"C:\\%s.csv",filename); for (i=0;i<3;i++) { if ( (ch[i]=(int *)malloc(4*30))==NULL ) { fprintf(stderr,"Cannot get memory <ch[%d]>.",i); return -1; } } fprintf(stderr,"%s\n",filewrite); if ((fp0=fopen(fileread,"rb"))==NULL) { fprintf(stderr,"Cannot open file %s\n",fileread); return 0; } fscanf(fp0,"%d", &num); if((fp1=fopen(filewrite,"wb"))==NULL) { fprintf(stderr,"Cannot open file!%s\n",filewrite); return 0; } for(i=0;i<50;i++) { fscanf(fp0,"%d %d %d",*(ch[0]),*(ch[1]),*(ch[2])); } for(i=0;i<num/100;i++) { for (k=0;k<100;k++) { fscanf(fp0,"%d %d %d",*(ch[0]),*(ch[1]),*(ch[2])); if ( feof(fp0) != 0 ) break; sum1=sum1+*(ch[0]); sum2=sum2+*(ch[1]); sum3=sum3+*(ch[2]); } fprintf(fp1,"%d %d %d\n",sum1,sum2,sum3); } fclose(fp0); fclose(fp1); return 0; }

専門家に質問してみよう