Cモジュールの落ちる現象について

このQ&Aのポイント
  • Cモジュールのモジュール作成中にたまに落ちるという問題が発生しています。
  • 現在作成中のCモジュールで、特定の関数の箇所で時々落ちることがわかりました。
  • 詳細な要因はわかっていませんが、関数のどこで問題が起きているかを特定することができていません。
回答を見る
  • ベストアンサー

Cモジュールが落ちる現象について

お世話になっております。 現在、C言語でモジュールを作成しているのですが、 下記の関数の箇所でたまにこけるということがわかりました。 この関数のどこでこけているかまでは、判断できていないのですが、 皆様のお力をお貸しいただけないでしょうか。 【ソース概要】 本モジュールはオブジェクトの監視に使用するものなのですが、 設定ファイルより、そのオブジェクトの監視時間帯を確認する関数です。 関数の引数として監視対象オブジェクト名を渡します。 また、本関数を実行するCモジュールは、異なる引数で同時に複数回実行されます。 【設定ファイル内容】 確認日付(曜日) オブジェクト名 監視開始時間1 監視終了時間1 監視開始時間2 監視終了時間2 0415 オブジェクト名 000000 040000 051500 240000   ⇒4月15日はオブジェクトを0時0分0秒から4時0分0秒までと、5時15分00秒から24時00分00秒まで監視する 0 オブジェクト名 000000 040000 051500 240000   ⇒0(日曜日)はオブジェクトを0時0分0秒から4時0分0秒までと、5時15分00秒から24時00分00秒まで監視する 【ソース】 int kansiqmcheck(char Object[256]){ FILE *fp ; time_t t; struct tm *ck_time ; char cktm[5],ckwk[4],line[256],ln[256],mes[512],obj[256] ; int rc=0 , nowtime=0, RC=0 , i ; char *ckdt[6] ; /* 変数初期化など */ memcpy(obj,0,sizeof(obj)); strcpy(obj,Object); memcpy(line,0,sizeof(line)); t=time(NULL); ck_time = localtime(&t); sprintf(cktm,"%02d%02d",ck_time->tm_mon + 1,ck_time->tm_mday); sprintf(ckwk,"%d ",ck_time->tm_wday); strcat(obj," "); for(i=0 ; i < 6 ; i++){ ckdt[i] = NULL; } /* 監視設定ファイルオープン */ if((fp = fopen(CHECKTIMEFILE,"r")) == NULL ){ memcpy(mes,0,sizeof(mes)); sprintf(mes,"%s: CheckTimeFileOpenError:%s" , Targ , CHECKTIMEFILE) ; log_out(mes); exit(1) ; } /* 監視設定ファイルより監視対象オブジェクトの当日の監視に関する情報を取得 */ while(fgets(line,256,fp)!=NULL) { if(strncmp(line,cktm,strlen(cktm)) == 0 && strstr(line,obj) != NULL){ rc=1; break ; }else if(strncmp(line,ckwk,strlen(ckwk)) == 0 && strstr(line,obj) != NULL){ rc=1; break ; } memcpy(line,0,sizeof(line)); } fclose(fp) ; fp = NULL ; /* 監視オブジェクトより、現時刻が監視時間帯に該当するか確認 */ if(strlen(line) > 2 ){ memcpy(ln,0,sizeof(ln)); strncpy(ln,line,strlen(line) - 1 ); i=0; ckdt[i] = strtok(ln," \n\0"); while(ckdt[i] != NULL || i < 6){ i++ ; ckdt[i] = strtok(NULL," \n\0"); } if( i < 2 ){ memcpy(mes,0,sizeof(mes)); sprintf(mes,"%s: CheckTimeInfoError(obj):%s %s %d" , Targ , CHECKTIMEFILE , line , i) ; log_out(mes) ; return; } while(1){ t=time(NULL); ck_time = localtime(&t); nowtime = ck_time->tm_hour * 10000 + ck_time->tm_min * 100 + ck_time->tm_sec ; for( i = 2 ; ckdt[i] != NULL ; i=i+2 ){ if( nowtime > atoi(ckdt[i]) && nowtime < atoi(ckdt[i+1]) ){ rc=0; break ; } } if( nowtime >= atoi(ckdt[i]) && nowtime < atoi(ckdt[i+1]) ){ rc=0; break ; } /* エラーログ確認用 */ if( strcmp(Targ,"ELG") == 0 ){ RC=1; } memcpy(mes,0,sizeof(mes)); sprintf(mes,"%s: 監視スキップ:%s" , Targ , obj ) ; log_out(mes); sleep(10); if(checkstat() != 0 ){ break ; } } } return(RC); }

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.3

>i=0; >ckdt[i] = strtok(ln," \n\0"); >while(ckdt[i] != NULL || i < 6){ >i++ ; >ckdt[i] = strtok(NULL," \n\0"); >} while文のループで、iが5のとき、i < 6 の条件を満たすので、 ループからは抜けずに i++; を実行しますから、iは6になりますよね。その状態で ckdt[i] = strtok(NULL," \n\0"); を実行すると、ckdt[6]に書き込もうとしますので、 >char *ckdt[6] ; オーバーフローしないでしょうか。 さっきの回答と同じで、取り越し苦労ならばいいのですけれど。

oniku029
質問者

お礼

何度もご回答いただきありがとうございます。 確かにオーバーフローしますね。 どうにもご指摘箇所が原因のような気がします。 ありがとうございます!

その他の回答 (4)

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.5

>objを初期化する際には >memcpy(obj,0,sizeof(obj)); >では、不足しているということでしょうか? 他の回答者さんからの回答にありましたとおり、 その引数の並びを使うのであれば memcpy()ではなくmemset()でしょうね。 memcpy()の第二引数はコピー元の領域を指すポインターです。 0としたときに、NULLか何かに勝手に置き換えてくれる、という保証があるのかどうか、 私にはわかりません。 まあ、sprintf()の準備として初期化している、ということであれば、 その初期化自体が不要である、と思います。

oniku029
質問者

お礼

ご回答ありがとうございます。 なんども同じ変数を使いまわしているのですが、 sprintfだけでは完全に初期化できなかったことがあったのでmemcpyを使用しました。 (本当はmemsetが正しいみたいですが、、、) とりあえず、想定どおりに動いていますので、memcpyのまま使います。

  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.4

>異なる引数で同時に複数回実行されます。 「スレッドセーフではない」って事かな? IOストリーム関数がスレッドセーフかどうかは、処理系によって異なるので「異なる引数で同時に複数回実行」するのであれば、使用している関数がすべてスレッドセーフなのかどうか確認する必要があります。

oniku029
質問者

お礼

ご回答ありがとうございます。 別プロセスとして起動するという意味で記載しておりました。 ですので、特に影響はないと思っているのですが、 私の勘違いの可能性もあり、記載させていただきました。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

>また、本関数を実行するCモジュールは、異なる引数で同時に複数回実行されます。 「同時に」というのはスレッドで実行されることがある。ということでしょうか。 >memcpy(obj,0,sizeof(obj)); memcpy()ではなくて、memset()ではないですか。 memcpy()とmemset()の違いは調べてみてください。 それも、その後にstrcpy()やsprintf()の出力先に使うのなら特に必要もないですけど。

oniku029
質問者

お礼

ご回答ありがとうございます。 >「同時に」というのはスレッドで実行されることがある。ということでしょうか。 別プロセスにて起動するという意味で記載しておりました。 >memcpy()ではなくて、memset()ではないですか。 たしかに、memsetですね。。。 なぜかmemcpyと勘違いしておりました。。。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.1

>char cktm[5],ckwk[4],line[256],ln[256],mes[512],obj[256] ; >memcpy(obj,0,sizeof(obj)); >strcpy(obj,Object); ここで、obj[]がたぶん満杯となっている状態のとき、 >strcat(obj," "); strcatして大丈夫なんでしょうか。 obj[]のサイズを多めにしておく必要は、ないでしょうか。 取り越し苦労かもしれませんけれど。

oniku029
質問者

お礼

asuncionさん ご回答ありがとうございます。 Objectには現状最大でも英数字で30文字までしかはいらないので、 objが満杯になることはないと思っています。 今、asuncionさんのご指摘をみて、思ったのですが、 objを初期化する際には memcpy(obj,0,sizeof(obj)); では、不足しているということでしょうか? 下記のリンク先より、上記のコマンドを選択したのですが・・・ http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1219043042

関連するQ&A

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; 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 c[11]; char sin[1000][1000]; 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 != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, 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 + 1900, 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\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;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, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • C言語のqsortについて

    下記の課題に取り組んでおり、qsortをファイルの行数分のみ出力するプログラムを書いているのですが if (strcmp(ad, "ASC") == 0) { qsort(sin,1000 , sizeof(sin[0]), cmp_u); if (sin[i][0] == 0) { break; } } else { qsort(sin, 1000, sizeof(sin[0]), cmp_d); if (sin[i][0] == 0) { break; } この書き方ではエラーが出てしまい、どなたか書き方を教えて頂けないでしょうか? 【課題】 電卓アプリケーションの作成  以下の機能を満たすアプリケーションを作成してください。  ※画面の表示やログの形式は原則として例示されている内容に従ってください。  1) 四則演算が出来ること  2) コンソールから計算対象となる数値と演算子を受け取る    例) 5 + 6  3) 結果をコンソール上に表示する    例) 11  4) 演算結果と実行した日、時間、秒をログファイルとして保存する    ログの上限は1000行とする(上限を超過するケースはひとまず考慮しなくて良い)    例) log.txt に 以下の内容を記録      2015/04/27 14:30:51, 5 + 6, 11  5) コンソールからパラメータを受け取り、ログを実行時間の昇順/降順に並べ替えて    コンソールに表示する    例) ASC を入力      2015/04/26 10:20:00, 5 + 6, 11      2015/04/27 14:30:51, 7 - 6, 1      2015/04/27 15:30:00, 7 + 8, 15      2015/04/28 14:30:51, 8 + 9, 17    例) DESC を入力      2015/04/28 14:30:51, 8 + 9, 17      2015/04/27 15:30:00, 7 + 8, 15      2015/04/27 14:30:51, 7 - 6, 1      2015/04/26 10:20:00, 5 + 6, 11 【現在のソースコード】 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; 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,n; FILE* fp; char c[11]; char sin[1000][1000]; 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 != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, 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 + 1900, 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\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); for (i = 0;i < 1000;i=i+1) { fgets(sin[i], sizeof(sin[0]), fp); //if (strcmp(sin, "NULL") == 0) { if (sin[i][0] == 0) { break; } } fclose(fp); printf("ASC or DESC: "); scanf(" %s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin,1000 , sizeof(sin[0]), cmp_u); if (sin[i][0] == 0) { break; } } else { qsort(sin, 1000, sizeof(sin[0]), cmp_d); if (sin[i][0] == 0) { break; } } for (i = 0;i < 1000;i = i + 1) { if (sin[i][0] == 0) { break; } printf("%s", sin[i]); } return 0; }

  • C言語の、戻り値/値渡し/アドレス渡しのついて

    【実装したコードに、戻り値/値渡し/アドレス渡しを用いたサブの関数を作成せよ。】 上記の課題に取り組んでいるのですが、何となく概念は分かったのですが、ソースコードに反映させようとすると詰まってしまって… どなたか教えて頂けないでしょうか? 『ソースコード』 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) 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[1000][1000]; 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; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / 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; }

  • 単方向リストに適当な値を入れて、逆順に表示するプログラムの仕組みがわかりません。

    以下のプログラムのReverceShowValue関数の仕組みがわかりません。 申し訳ございませんが、ご教授の方、よろしくお願いします。 #if 1 /* リスト構造の実装 * 再帰関数を用いて逆順に表示 */ #include <stdio.h> #include <stdlib.h> typedef struct object{ int value; struct object *next; }OBJ; OBJ* AllocateBlock(int value) { OBJ *block; block = (OBJ*)malloc(sizeof(OBJ)); if(block == NULL){ printf("Allocate Error\n"); exit(1); } block->value = value; block->next = NULL; return block; } void ReverceShowValue(OBJ *p) { if(p != NULL){ ReverceShowValue(p->next); printf("%d\n", p->value); } } void FreeAllocate(OBJ *p_top) { OBJ *temp; while(p_top != NULL){ temp = p_top->next; free(p_top); p_top = temp; } } int main(void) { OBJ *top = NULL; OBJ *temp; int i; for(i = 0;i < 10;i++){ if(top == NULL){ top = AllocateBlock(i); temp = top; } else{ temp->next = AllocateBlock(i); temp = temp->next; } } ReverceShowValue(top); FreeAllocate(top); return 0; } #endif

  • 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++の初期化チェックに関する質問です

    C++のクラスの初期化済み、未初期化を調べる方法についてご質問させていただきます。 以下のプログラムを実行するとコメント部分//Aで実行時にエラーが発生すると思います。 class Object { int *arg ; public : Object( int len ) { arg = new int[ len ] ; } public : ~Object( ) { delete[ ] arg ; } } ; int main( ) { Object obj1 = Object( 100 ) ; Object *obj2 ; obj1 = *obj2 ; // A return 0 ; } エラー理由はobj2が初期化されていないからだと分かるのですが、 プログラマー側でobj2が初期化されているか調べる方法はあるのでしょうか? 定義時にObject *obj2 = NULL ;としてif文で回避する以外に方法が ありましたら、ぜひご教授願います。

  • C言語の動的配列について

    C言語で下記の課題に取り組んでいるのですが、ファイルから入力された行数分を出力する事に対して、苦戦しております。 恐らく動的配列を使うと思うのですが・・・書き方が分からず、どなたか教えて頂けないでしょうか? 「課題文」 1) 四則演算が出来ること    2) コンソールから計算対象となる数値と演算子を受け取る      例) 5 + 6    3) 結果をコンソール上に表示する      例) 11    4) 演算結果と実行した日、時間、秒をログファイルとして保存する      ログの上限は1000行とする(上限を超過するケースはひとまず考慮しなくて良い)      例) log.txt に 以下の内容を記録        2015/04/27 14:30:51, 5 + 6, 11    5) コンソールに表示する 「ソースコード」 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> int main() { int num1, num2; char op; float answer; int r,i,n; FILE* fp; char c[11]; char sin[][1000]; fp = fopen("log.txt", "a"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, 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 + 1900, 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\n", &c); if (strcmp(c, "no") == 0) { break ; } } for (;;) { fgets(sin[i], sizeof(sin[0]), fp); } fclose(fp); for (i = 1; i <= n; i++) { printf("%s", sin[i]); } return 0; }

  • ポインタのキャストについて

    下記のようなクラス定義があるとします。 説明のため、関係のない要素は省略し簡略化しています。 class HOGE { int a; char c; LPSTR lpszStr; // メンバ関数定義 } class HOGE_Derived : public HOGE { LPSTR _lpszStr; HOGE_Derived& operator= (HOGE& obj_HOGE); HOGE_Derived& operator= (HOGE_Derived& obj_HOGE_Derived); // メンバ関数定義 } このとき、下記のようなコードで演算子のオーバーロードを行っていますが、これは正しいのでしょうか? HOGE_Derived& HOGE_Derived::operator= (HOGE& obj_HOGE) { memcpy((HOGE*)this, &obj_HOGE_Derived, sizeof(HOGE)); lpszStr = NULL; // lpszStrのディープコピー _lpszStr = new char[strlen(obj_HOGE.lpszStr) + 1]; strcpy(_lpszStr, obj_HOGE.lpszStr); lpszStr = _lpszStr; return *this; } HOGE_Derived& HOGE_Derived::operator= (HOGE_Derived& obj_HOGE_Derived) { memcpy((HOGE*)this, (HOGE*)&obj_HOGE_Derived, sizeof(HOGE)); lpszStr = NULL; // lpszStrのディープコピー _lpszStr = new char[strlen(obj_HOGE_Derived.lpszStr) + 1]; strcpy(_lpszStr, obj_HOGE_Derived.lpszStr); lpszStr = _lpszStr; return *this; } 期待した動作は、まず最初のmemcpyで、obj_HOGEまたはobj_HOGE_Derivedオブジェクトのうち、基本クラス(HOGE)に存在するフィールドint aとchar cのみをコピーしたいのです。 memcpyによってこのようなコピーを行った時、処理系に依存せず期待した通りコピーできるものなのでしょうか? そもそも、このようなコピーの仕方自体、自然なやり方でしょうか? 気になるのは、HOGE_Derivedクラスのオブジェクトのメモリ内のデータの並びがどのようになっているのかと言うことです。 HOGE_Derivedクラスのポインタを、その基本クラスであるHOGE型にキャストした時に、このポインタで見えるエリアが、HOGE_Derivedクラスの中のHOGEクラスの部分だけと言うことは分かっているのですが、その部分のメモリ上の並びが必ず基本クラスの各フィールド→派生クラスで定義されたフィールドの順になっているのかどうか分かりません。 よろしくお願いします。

  • プログラムが止まってしまいます

    Visual Studio 2012 c++ でプログラムを動かそうと思っているのですが、デバッグ開始すると画像のようなウィンドウが出て実行途中で止まってしまいます。 呼び出し履歴のint mqoLoadFileのソースを貼ります. int mqoLoadFile( MQO_OBJECT *mqoobj, char *filename, double scale, unsigned char alpha) { FILE *fp; MQO_OBJDATA obj[MAX_OBJECT]; MQO_MATDATA *M = NULL; char buf[SIZE_STR]; // 文字列読み込みバッファ char path_dir[SIZE_STR]; // ディレクトリのパス char path_tex[SIZE_STR]; // テクスチャファイルのパス char path_alp[SIZE_STR]; // アルファテクスチャファイルのパス int n_mat = 0; // マテリアル数 int n_obj = 0; // オブジェクト数 int i; // MaterialとObjectの読み込み fopen_s(&fp,filename,"rb"); if (fp==NULL) return 0; mqoobj->alpha = alpha; memset(obj,0,sizeof(obj)); i = 0; while ( !feof(fp) ) { fgets(buf,SIZE_STR,fp); // Material if (strstr(buf,"Material")) { sscanf_s(buf,"Material %d", &n_mat); M = (MQO_MATDATA*) calloc( n_mat, sizeof(MQO_MATDATA) ); mqoReadMaterial(fp,M); } // Object if (strstr(buf,"Object")) { sscanf_s(buf,"Object %s", obj[i].objname);//ココの実行中に止まる mqoReadObject(fp, &obj[i]); i++; } } n_obj = i; fclose(fp);

専門家に質問してみよう