• 締切済み

C言語 カウント ファイル出力

C言語 ファイル入出力 文字カウント C言語の勉強をしています。 ファイル入出力+文字カウントがわからなく質問させてもらいました。 問題の内容は文字EADBACABEEAACが入っているファイルmon1.txtを読み込み 何回文字が登場するのかをカウントするというものです。 カウント結果はコマンドプロンプトとmon1.txtに出力します。 自分でかけるところまで書いてみたのですが※の部分がどうやれば良いのかわからず質問させていただきました。 ご教授よろしくお願いします。 #include <stdio.h> #include <ctype.h> int main() { FILE *fp; char ch; int i; int a; int b; int c; int d; int e; fp = fopen("mon1.txt", "w"); if(fp == NULL) { printf("出力ファイルオープンエラー\n"); return -1; } for(i = 0; ※ == '\0'; i++) { switch (※) { case 'A': a++; break; case 'B': b++; break; case 'C': c++; break; case 'D': d++; break; case 'E': e++; break; default: break; printf("A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",a,b,c,d,e); fprintf(fp, "A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",a,b,c,d,e); } } return 0; }

みんなの回答

回答No.4

ANo2: × while (*pBufPtr != NULL) ○ while (*pBufPtr != '\0')

回答No.3

一部間違えてました。 sprintf(writeBuf, "A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",count[0],count[1],count[2],count[3],count[4]); でした。

回答No.2

ソースの一部なら良いのですが、全てのソースだったとしたら、 このソースには問題があります。 ファイルの読み書きで開いていない。  "w"ではなくて"rw"とするべきでしょう。  その後にfseek等で位置を戻したり文字数が読み込みより少ないなら  後ろのデータを消したりしないといけないので、  "r"で開いた後に改めて"w"したほうが楽と思います。 forの使い方とswitchの使い方がまだ理解できてないようなので 再度確認してください。 以前の回答者が説明しているので割愛します。 以下サンプルです。 エラーチェックは適当です。 int main() { FILE *fp; char buf[50]; char writeBuf[100]; char *pBufPtr; char count[5]; memset(buf, 0x00, sizeof(buf)); memset(writeBuf, 0x00, sizeof(writeBuf)); memset(count, 0x00, sizefo(count)); if ((fp = fopen("mon1.txt", "r")) == NULL) { return -1; } fgets(buf, sizeof(buf), fp); fclose(fp); pBufPtr = buf; while (*pBufPtr != NULL) { switch(*pBufPtr) { case 'a': count[0]++; break; case 'b': count[1]++; break; case 'c': count[2]++; break; case 'd': count[3]++; break; case 'e': count[4]++; break; default: break; } pBufPtr++; } if ((fp = fopen("mon1.txt", "w")) == NULL) { return -1; } sprintf(writeBuf, "A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",a,b,c,d,e); printf(writeBuf); fprintf(fp, writeBuf); fclose(fp); return 0; }

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

> ※の部分 まず、日本語(あるいは、あなたの得意な自然言語)で、「※の部分」に何を書きたいか説明できますか? で、それを書けたとしても、正しく動作しないと思われます。 > for(i = 0; ※ == '\0'; i++) { for(式1;式2;式3) は 「式2が真の間ループする」 です。 ※ == '\0' だと、 「※が'\0'の間はループし、'\0'でなくなったらループを終了する」です。 「文字列が続いている間ループする」のなら、ループしたいのは '\0'で無いときで、 '\0'になったら終了ですよね? > printf("A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",a,b,c,d,e); > fprintf(fp, "A[%d]回、B[%d]回、C[%d]回、D[%d]回、E[%d]回",a,b,c,d,e); この2つは、絶対に実行されません。 その理由はわかりますか? {} の対応をよくかんがえましょう

関連するQ&A

  • c言語 文字数のカウント 合わない

    こんにちは. c言語のプログラムを書いて疑問に思ったことがあるのでお尋ねします.以下のプログラムで,data.txtに書かれている文字を読み取り,総文字数,スペース,タブ,ニューラインの数をカウントしようと思いました.スペース,タブ,ニューラインは正しくカウントするのですが,総文字数char_counterの数が合いません.ファイルから文字を読み取る時に使った,loop_counterもchar_counterと同義だと思いloop_counterを表示させてみたところ,こちらは文字数を正しくカウントしているようです. I am checking how it works. という文字列が入ったファイルなのですが,char_counterは100文字を越えてしまいます.どうしてloop_counterとchar_counterで違う値が出てしまうのでしょうか?解答をお待ちしております.その他正しく動いている部分に関しても,変な書き方のところがあればそれも指摘して頂ければ嬉しいです. なお,原因解明のために試行錯誤していて,ファイルの読み取りでは配列の[]の中身を足していき,文字を比較する際にはポインタの値を足していくという変なプログラムになっています.ご了承下さい. #include <stdio.h> #include <stdlib.h> #define BUF_SIZE (256) #define EXIT_FAILURE (1) int main() { FILE *fp; char read_line[BUF_SIZE]; int loop_counter = 0; fp = fopen("data.txt", "r"); if(fp == NULL) { printf("file open error\n"); exit(EXIT_FAILURE); } while((read_line[loop_counter] = getc(fp)) != EOF) { loop_counter++; } read_line[loop_counter] = '\0'; fclose(fp); if(fp == NULL) { printf("file close error\n"); exit(EXIT_FAILURE); } /* this counts the whole char numbers including space*/ int char_counter = 0; int space_counter = 0; int tab_counter = 0; int newline_counter = 0; char *read_line_address; read_line_address = &read_line; while(*read_line_address != EOF) { char_counter++; switch(*read_line_address) { case ' ': space_counter++; break; case '\t': tab_counter++; break; case '\n': newline_counter++; break; default: break; } read_line_address++; } printf("%s\n", read_line); printf("space %d ", space_counter); printf("tab %d ", tab_counter); printf("newline %d ", newline_counter); /* printf("whole chars %d\n", char_counter); */ printf("whole chars %d\n", loop_counter); return 0; }

  • c言語  2つのファイルを行ごとに読み込むプログラミング

    c言語  2つのファイルを行ごとに読み込むプログラミング 0.txt と 1.txt という2つのテキストフォルダがあり 0.txt の中身は a a b b 1.txt の中身は c c d d というものとします。 これら2つのフォルダを読み込むとき まず1つのフォルダの1行目(a a)を表示し 他方の1行目(c c) 2行目(d d)を表示させて 続いて1つのフォルダの2行目(b b)を表示し 他方の1行目(c c) 2行目(d d)を表示させたいのです。 つまり実行結果が a a c c a a d d b b  ←理想の実行結果です c c b b d d となるようにしたいのですが #include <stdio.h> #include <stdlib.h> #define STR_MAX 256 int main(void) { FILE *fp, *fp2; int i, j, k; char buf[STR_MAX]; char buf2[STR_MAX]; fp = fopen("0.txt", "r"); fp2 = fopen("1.txt", "r"); if (fp == NULL && fp2 == NULL){ printf("\n"); } while(fgets(buf, STR_MAX, fp) != NULL){ while(fgets(buf2, STR_MAX, fp2) != NULL){ printf("%s%s", buf,buf2); } printf("\n"); } fclose(fp); fclose(fp2); return 0; } このプログラミングの実行結果は a a c c a a d d となり、0.txtの2行目(b b)は表示されません。 おそらく while 文 を2重にすることで 不具合が起きているのだと思うのですが 色々と調べた結果、これ以外に プログラミングが思いつきません。 私の理想の実行結果にするためには どこを訂正させると良いのでしょうか? 恐れ入りますが ご回答 どうかよろしくお願いいたします。

  • ファイルの入力、出力

    #include<stdio.h> int main(){ int a,b; FILE *fp0, *fp1;   fp0 = fopen("test1.dat", "r"); if( fp0 == NULL ){ printf("Cannot open test1.dat"); exit(1); } fp1 = fopen("file.txt", "w"); while((fscanf(fp0, "%d %d", &a,&b)) != EOF){ fprintf(fp1, "%d %d\n", a*a,b*b); } fclose(fp0); fclose(fp1); return(0); } test1.datファイルを読み込んで、変数a,bに値をいれ、 その二乗結果をfile.txtに書き込むプログラムなのですが test1.datファイルに書き込まれてる値をどのようにa,bに代入されているのかわかりません。 例えば test1.datが 1 2 3 4 5 であると、 file.txtには 1 4 9 16 25 16 と書き込まれています。 test1.datが 1 1 2 2 3 3 であると file.txtには 1 1 4 4 9 9 となっています。 どのように、変数に値が入るのでしょうか??

  • C言語でファイルを出力

    ファイルの中に変数をいれて複数のファイルをつくろうとしたのですが、 できたファイルの後に?マークがついてきます。 file = fopen("filename.txt", "w"); for(j=0; j<30; j++){ fprintf(file ,"%d.dat\n",j ); } fclose(file); file2 = fopen("filename.txt", "r"); として、ファイル名を書いたファイルをつくってから、 for(k=0; k<30; k++){ fgets(fp,sizeof(fp),file2); file_out = fopen(fp,"w"); 省略 fprintf(file_out, %e %e \n",a ,b); fclose(file_out); } fclose(file2); をして、30個のファイルを出力すると、 0.dat? 1.dat? 2.dat? . . . 29.dat? というファイルができてしまいます。 ファイルの中はしっかりできています。 なにか解決法を知っている方がおりましたら、どうか教えて下さい。

  • c言語 DFAのプログラム

    DFAを受理するプログラムを組んでいるのですが、コンパイルして動作させるとすぐに終わってしまいます。 どこがいけないのでしょうか…。助言を求めています。 手探りでやっているのですが、ファイル読み込みなど、基本的な所からわかっていない状態です。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> enum { NFA_0_2_3_5, NFA_0_1_2_3_5_6_7_8_10_11_12, NFA_4_7_8_10, NFA_11_12, NFA_9_12, NFA_13_15_16, NFA_14 }; int regex(char *txt, int idx); int DFA_match(char *txt, int startIndex); int main (int argc, char *argv[]) { int c, i, m, idx; char text[1024], *pattern; FILE *fp; pattern = argv[optind++]; for (i = optind; i < argc; i++) { fp = fopen(argv[i], "r"); if (fp == NULL) { fprintf(stderr, "File %s: open failed.\n", argv[i]); } else { while (fgets(text, sizeof(text), fp) != NULL) { m = 0; for (idx = 0; (idx = regex(text, idx)) >= 0; idx++) { m++; } if (m > 0) { printf("%s: %s", argv[i], text); } } } } return 0; } int DFA_match(char *txt, int startIndex) { int DFAstate = NFA_0_2_3_5; int acceptLen = -1; int i; for (i = startIndex; txt[i] != '\0'; i++) { switch (DFAstate) { case NFA_0_2_3_5: switch(txt[i]){ case 'x': DFAstate = NFA_0_1_2_3_5_6_7_8_10_11_12; break; case 'z': DFAstate = NFA_4_7_8_10; break; default: return acceptLen; } break; case NFA_0_1_2_3_5_6_7_8_10_11_12: switch(txt[i]){ case 'x': DFAstate = NFA_0_1_2_3_5_6_7_8_10_11_12; break; case 'z': DFAstate = NFA_4_7_8_10; break; case 'y': DFAstate = NFA_9_12; break; default: return acceptLen; } break; case NFA_4_7_8_10: switch(txt[i]){ case 'x': DFAstate = NFA_11_12; break; case 'y': DFAstate = NFA_9_12; break; default: return acceptLen; } break; case NFA_11_12: switch(txt[i]){ case 'y': DFAstate = NFA_9_12; break; default: return acceptLen; } break; case NFA_9_12: switch(txt[i]){ case 'y': DFAstate = NFA_13_15_16; acceptLen = i; break; default: return acceptLen; } break; case NFA_13_15_16: switch(txt[i]){ case 'x': DFAstate = NFA_14; break; default: return acceptLen; } break; case NFA_14: switch(txt[i]){ case 'y': DFAstate = NFA_13_15_16; acceptLen = i; break; default: return acceptLen; } break; } } return acceptLen; } int regex(char *txt, int idx) { int i; for (; idx < strlen(txt); idx++) { if ( (i = DFA_match(txt, idx)) > 0) { printf("matched!\n"); return idx; } } return -1; }

  • C言語 ファイルの出力

    こんにちは。 現在C言語学習中でファイルの出力でエラーが発生したのですが、どのようにエラーを起こしているのかわかりません。 ご指摘をお願いします。 #include<stdio.h> int main(void) { FILE *fp = NULL; fp = fopen("test1.txt", "w"); if(fp == NULL){ printf("ファイルをオープンでいませんでした。\n"); return -1; } else{ printf("ファイルをオープンしました。\n"); } fputs("Hello!\n", fp); fputs("Hello World!\n", fp); printf("ファイルに書き込みました。\n"); fclose(fp); printf("ファイルをクローズしました。\n"); int i; scanf("%d", &i); return 0; } エラーの内容は 1>LINK : fatal error LNK1104: ファイル 'C:\Users\拓哉\Documents\Visual Studio 2010\Projects\sample.c\Debug\sample.c.exe' を開くことができません です。現在使用中のC言語環境は上記の通り、Visual Studio 2010です。 学習仕立てで、あまりプログラミングについて知りません。 よろしければ、他に何か間違いがあればご指摘お願いします。

  • C言語・Windows 文字の出力ができない

    C言語でWindowsプログラミングをしているのですが、文字がうまく扱えなくて困っています。 txtファイルから読み込んだ文字を"@@"のところで区切って、ウィンドウに描画するだけなのですが、うまくできません。 例) contents.txtファイル(以下中身です。) データ整理@@ファイル、フォルダをインポート@@アドレスからインポート@@txtとpdf(html,jpg,bmp)を等価に扱う@@検索@@タグ これをウィンドウに  データ整理  ファイル、フォルダをインポート  アドレスからインポート  txtとpdf(html,jpg,bmp)を等価に扱う  検索  タグ というように表示したいのですが、なぜか  データ整理  ファイル、フォルダをインポートアドレスからインポート  アドレスからインポート  txtとpdf(html,jpg,bmp)を等価に検索  検索  タグ のように表示されてしまいます。 (二段目と四段目がおかしくなっています、書き間違えではないです、念のため) 初心者なので、勉強不足による些細な間違いかもしれませんが、なにとぞ知恵をお貸しくださいm(_ _)m 以下、ソースコードのメッセージ処理部分です。 ウィンドウ生成のひな型は問題ないと判断しました。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int i = 0, j = 0, k = 0; int fp; HDC hdc; PAINTSTRUCT ps; char script[1000]; static char title[100][30]; switch (msg){ //ウィンドウ生成時 case WM_CREATE: fp = Reading("./contents.txt", script); if(fp == -1){ MessageBox(hWnd, (LPCSTR)"contents.txtが存在しない", (LPCSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION); }else{ for(;;){ if(script[i] == '\0'){ title[j][k] = '\0'; break; }else if(script[i] == '@' && script[i+1] == '@'){ title[j][k] = '\0'; i += 2; j++; k = 0; }else{ title[j][k] = script[i]; i++; k++; } } for(i = 0; i <= j; i++){ } } break; //ウィンドウの描画 case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SetBkMode(hdc, TRANSPARENT); for(i = 0; i <= j; i++){ TextOut(hdc, 0, MOJI_SIZE * i, (LPSTR)title[i], strlen(title[i])); } EndPaint(hWnd, &ps); break; //ウィンドウの削除 case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); } //読み込み int Reading(const char* filename, char* script) { int pos = 0; char c; //スクリプトファイル FILE* fp; //スクリプトファイルを開く fp = fopen(filename, "r"); if( fp == NULL ) { //ファイル読み込みに失敗 return -1; } for( ;; ) { //一文字読み込み c = fgetc( fp ); //ファイルの終わりかどうか if( feof( fp ) ) { script[pos] = '\0'; break; } //改行文字が出てきた場合,無視 if( c != '\n' && c != '\t' ) { //書き込み script[pos] = c; //文字書き込み位置をずらす pos++; } } fclose(fp); return 0; }

  • 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言語の引数について

    「戻り値、値渡し、ポインタ渡しを用いたサブ関数を実装する」 という課題に対して、calc_proc関数を実装したのですが、下記のコード提出後に 「引数で値をmainに戻すパターンを実装する」 との要望を受けたのですが、やり方が分からず、どなたか修正方法、追加方法を教えて頂けないでしょうか? 「ソースコード」 #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) { switch (op) { case '+': (float)*n1 + n2; break; case '-': (float)*n1 - n2; break; case '*': (float)*n1 * n2; break; case '/': if (n2 == 0) { puts("input error"); return 1; } (float)(float)*n1 / n2; break; default: printf("input error"); } 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 r,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) { r = scanf("%d%c%d", &num1,&op, &num2); if (r != CALC) { puts("input error"); return 1; } answer = calc_proc(&num1, op, num2); 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"); 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言語を使ってプログラムを作っています。 20000個のデータを読み込んで、200個ずつに区切り、別々のテキストファイルで出力するというものです。 最初につくったのは、以下の通りです。 *********************************************** FILE *fp; { int b,i=0; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; fp = fopen("D1.txt","w"); for(i=0;i<=199;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); fp = fopen("D2.txt","w"); for(i=200;i<=399;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); ・・・ ***************************************** これだと20000まで繰り返し記述しなければならずかなり困難だと思いました。そこで、ループを作ろうとしたのですが、テキストファイルをループを使って複数作成する方法がわかりません。 以下のようなプログラムを作ったのですが、テキストファイルが一つしか作られませんでした。 どのように記述すればよいのでしょうか? **************************************** FILE *fp; { int a,i=0; int b=1; int c=199; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; start: fp = fopen("D[1+b].txt","w"); for(i=a;i<=c;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); if(i > c) c = c+200; a = a+200; b++; goto start; fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); fclose(fp); } } ****************************************** よろしくお願い致します。

専門家に質問してみよう