• 締切済み

処理内容

以下の3点について有識者へ伺いたいです。 (1)このプログラムが何をするものなのか (2)最後のfor文が無限ループしてしまう理由 (3)可能であれば、各行(各処理)が何をしているのかを教えていただければ嬉しいです。 #include <stdio.h> #include <string.h> #define NUM_HASH 10 char *hash_key[NUM_HASH]; unsigned char hash_val[NUM_HASH]; unsigned char calc_hash_value(const char *key) { int i; unsigned char val = 0; for (i = 0; key[i] != '\0'; i++) val += key[i]; return val; } int main(int argc, char *argv[]) { int i, cnt = 0; unsigned char val; for (--argc, ++argv; argc > 0 && cnt < sizeof(hash_val)/sizeof(hash_val[0]); --argc, ++argv, cnt++) { hash_key[cnt] = *argv; hash_val[cnt] = calc_hash_value(hash_key[cnt]); } for (val = 0; val < 256; val++) { for (i = 0; i < cnt; i++) { if (val == hash_val[i]) { printf("key = |"%s|"|n", hash_key[i]); printf("hash value = 0x%.2X|n", hash_val[i]); } } } return 0; }

  • ya-cha
  • お礼率68% (184/268)

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

unsigned charの値域を良く考えて見ましょう unsigned charで 256(0x100)が表現できるのかどうか ・・・

ya-cha
質問者

お礼

ご回答ありがとうございました。 unsigned char は 0~255まででした! for文でvalの値が256になるタイミングでオーバフローしてしまうという事ですね!? ありがとうございました!

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.3

確かにこれでは永久にループしますね。 これが故意でなければ、プログラムの意図も探る 根拠があるのかな? と思います。 プログラムの意図も分からない、完成もしていな い、そんなプログラムについて質問される理由に 興味があります。何故?

ya-cha
質問者

お礼

ご回答ありがとうございます。 もし可能であれば、なぜ無限ループしてしまうのか教えてください。 お願いいたします。 ちなみに、無限ループしてしまうのは故意です。 質問するのは、この問題を今解いていて、分からないだけです。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

>(1)このプログラムが何をするものなのか >(3)可能であれば、各行(各処理)が何をしているのかを教えていただければ嬉しいです。 入手した先から確認すればいいだけでは? >(2)最後のfor文が無限ループしてしまう理由 こっち for (val = 0; val < 256; val++) なら、 オーバフロー起こしてるから永久にループする。

ya-cha
質問者

お礼

ご回答ありがとうございます。 入手先への確認が不可能なのでこちらへしつもんさせていただきました。 また、ほとんど知識が無いのでよく分かりませんが、オーバフローしてしまうというのはどういう意味ですか? たびたび恐れ入りますが、可能であればご回答をお願いいたします。

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

そのままコピー&ペーストしてコンパイルしたところ、 > printf("key = |"%s|"|n", hash_key[i]); この行でエラーが出ました。 こちらが勝手に修正すると、お手元のコードと食い違ってしまうおそれがあります。 そこで、コンパイルエラーが出ないコードをあらためて載せていただけますか?

ya-cha
質問者

お礼

ご回答ありがとうございます。 すいませんでした。以下の出力処理を間違えていました。 誤) printf("key = |"%s|"|n", hash_key[i]); printf("hash value = 0x%.2X|n", hash_val[i]); 正) printf("key = \"%s\"\n", hash_key[i]); printf("hash value = 0x%.2X\n", hash_val[i]); 以上、よろしくお願いいたします。

関連するQ&A

  • ラベリング処理プログラム

    画像のラベリング処理プログラムを作っているんですが どうもうまく実行できません。よければ教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> int column, row; unsigned char val[4] = {0,0,0,0}; unsigned char tmp[255]; int pos_y[4] = {-1, 0, 1, 0}; int pos_x[4] = {0, 1, 0, -1}; int i, j, x, y, label, level, label1; int label_count = 1; unsigned char *in, *out; void labeling_main(); void labeling_search(); void labeling_main() { for(i = 0; i < y; i++){ for(j = 0; j < x; j++){ printf("aaa\n"); if(out[i * x + j] == 255){ printf("bbb\n"); fflush(stdout); out[i * x + j] = label_count; labeling_search(label_count, i, j); label_count++; } } } } void labeling_search(int label_count, int x, int y) { for(i = 0; i < 4; i++){ if(out[(pos_y[i] + y) * x + (pos_x[i] + x)] == 255){ out[(pos_y[i] + y) * x + (pos_x[i] + x)] = label_count; labeling_search(label_count,(pos_y[i]+y),(pos_x[i]+x)); } } printf("ccc\n"); } int main(int argc, char *argv[]) { int result; int head, Magic; unsigned char *image, *in, *out, *res, *ros; FILE *fin, *fout; if(argc!=3){ printf("Usage : %s input output\n",argv[0]); exit(1); } fin = fopen(argv[1],"rb"); /* -------------------- ヘッダ取得ここから -------------------- */ fgets(tmp,255,fin); if(tmp[0]!='P') return 0; sscanf(tmp,"P%d",&Magic); if(Magic < 1 || Magic > 6) return 0; do fgets(tmp,255,fin); while(tmp[0]=='#'); sscanf(tmp,"%d %d",&x,&y); if(x < 1 || y < 1) return 0; fgets(tmp,255,fin); sscanf(tmp,"%d",&level); /* ヘッダの確認 */ printf("P%d\n",Magic); printf("%d %d\n",x,y); printf("%d\n",level); /* 画素の読み込み */ in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in,sizeof(unsigned char),x*y,fin); fout = fopen(argv[2],"wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); out = (unsigned char *)malloc(sizeof(unsigned char) *x*y); //2値画像 for (i = 0; i < y; i++) { for (j = 0; j < x; j++){ if(in[i * x + j] > 120){ out[i * x + j] = 0; }else if(in[i * x + j] <= 120){ out[i * x + j] = 255; } } } labeling_main(); printf("Max label number:%d\n",label_count); free(in); free(out); fclose(fin); fclose(fout); } コンパイルは通るのですが実行するとlabeling_mainの if文でセグメンテーションが出てしまいます。

  • 二行目の*の意味を教えてください。

    #include <stdio.h> int main(int argc, char *argv[]) { int i; for ( i = 0; i < argc; i++ ){ printf("argv[%d]=%s\n", i, argv[i]); } return argc; }  以上プログラムで、二行目の*の意味を教えてくさい。  6行目のargvには*が付いていません!?  よろしくお願いします。

  • ファイルの内容の表示

    実行時のコマンドライン引数で指定したファイルの内容を、行番号付きで画面に表示するプログラムを作る という問題です。ヒントも与えられています。 行番号付きの表示、コマンドライン引数の利用。両者を組み合わせればできるはずだ >  main関数の引数にargcとargvを指定して、コマンドライン引数をファイル名として利用する。キーボード入力を促す文(プロンプト)や改行チェックは不要なので書かないこと >  コマンドライン引数が指定されない場合は、メッセージを表示してプログラムを終了 >  ファイルの内容を画面表示する処理は、ユーザー定義関数put_file_contentsに記述する。仮引数には文字型のポインタ変数をひとつ指定し、ファイル名を受け渡せるようにする。put_file_contents自体の型は整数型(int)で、正常終了なら返り値0を返すこと。 行番号付きのプログラム#include<stdio.h> > int put_file(char *filename); > > int main() > { > char line[50]; > char *ptr; > > printf("ファイル名を入力:"); > fgets(line,sizeof(line),stdin); > ptr = line + strlen(line) - 1; > if(*ptr == '\n') { > *ptr = '\0'; > } > > put_file(line); > > return 0; > } > > int put_file(char *filename) > { > FILE *fp; > char buf[100]; > int line_no; > > fp = fopen(filename,"r"); > if (fp == NULL){ > printf("%sを開けません\n",filename); > return 1; > } > line_no = 1; > while (fgets(buf,sizeof(buf),fp) != NULL){ > printf("%3d: ",line_no); > printf("%s",buf); > line_no++; > } > fclose(fp); > > return 0; > } で、コマンドライン引数のプログラムは#include<stdio.h> void write_key_inputs(char *filiname); int main(int argc, char *argv[1]) { write_key_inputs(argv[1]); return 0; } void write_key_inputs(char *filename) { FILE *fp; char buf[100] ; fp = fopen(filename,"w"); while(fgets(buf, sizeof(buf),stdin) != NULL) { fputs(buf, fp); } fclose(fp); return ; } です。これらを組み合わせて少しいじると出来るみたいなのですが、できていません。ちなみに私が考えたプログラムは #include<stdio.h> int put_file_contents(char *filename); int main(int argc,char *argv[]) { int i; if(argc == 1){ printf("コマンドライン引数がありません\n"); return 1; } for(i = 0;i<argc;i++) printf("argv[%d]は「%s」です\n",i,argv[i]); put_file(i); return 0; } int put_file(char *filename) { FILE *fp; char buf[100]; int line_no; fp = fopen(filename,"r"); line_no = 1; while (fgets(buf,sizeof(buf),fp) != NULL){ printf("%3d: ",line_no); printf("%s",buf); line_no++; } fclose(fp); return 0; } です。コマンドライン引数は表示されるのですが、行番号が表示されません。どうしたらいいでしょうか??

  • ファイルポインタによるコアダンプの解決法

    タイトルの通りです。以下のプログラムを実行するとコアダンプがでるので、解決法を教えて頂きたいです。 5つのdatファイルの読み込みはうまくいきました。15個に増やしたところ、コアダンプが表示されました。 ファイルポインタを使わずに実行してみたら15個でも大丈夫でしたので、ファイルポインタが原因かと思います。 typedef struct{ int class; int** matrix; }pattern_struct; int main(int argc,char* argv[]) { pattern_struct *learn; FILE *fp; int width,height; int i,j,k,value; learn=(int*)malloc(argc*sizeof(int)); //ファイルからの学習データの読み込み for(k=1;k<argc;k++){ fp=fopen(argv[k],"r"); printf("%s\n",argv[k]); printf("学習する数字を入力してください "); scanf("%d",&learn[k].class); fscanf(fp,"%d %d",&width,&height); learn[k].matrix=(int**)malloc(height*sizeof(int*)); for(i=0;i<height;i++) learn[k].matrix[i]=(int*)malloc(width*sizeof(int)); for(i=0;i<height;i++){ for(j=0;j<width;j++){ fscanf(fp,"%d",&value); learn[k].matrix[i][j]=value; } } fclose(fp); fp=NULL; } return 0; }

  • C言語でファイルの内容を strtok関数 を使って数字と文字を分けて

    C言語でファイルの内容を strtok関数 を使って数字と文字を分けて配列に格納したいのですが、うまくできません。 どこが駄目なのかご指摘をお願いします! ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int i=0; int num[10]; char na[10]; fp=fopen(argv[1],"r"); while(fgets(str,sizeof str,fp)!=NULL); tp = strtok ( str, " " ); while(tp != NULL ) { num[i]=atoi(tp); tp = strtok( NULL," "); if ( tp != NULL ){ na[i]=*tp; } i++; } printf("%d\n%s",num[0],na[0]); printf("%d\n%s",num[1],na[1]); fclose(fp); return 0; }

  • カラー画像からグレースケール画像フォーマットの変換

    カラー画像からグレースケール画像フォーマットの変換するプログラムなんですが、いまいち理解できていません。 プログラムはRGB構造体を使ってのものなんですが添削お願いいたします。 #include<stdio.h> #include<stdlib.h> typedef struct _RGB { unsigned char r; unsigned char g; unsigned char b; } RGB; int main(int argc, char *argv[]) { int x, y; unsigned char *in, *out; int i, j, Magic, level; unsigned char tmp[255]; RGB **pixels; int width = 255; int height = 255; int size = width * height; FILE *fin, *fout; if(argc != 3){ printf("Usage : %s input outpu \n", argv[0]); exit(1); } fin = fopen(argv[1], "rb"); fgets(tmp, 255, fin); if(tmp[0] != 'P'){ return 0; } sscanf(tmp, "P%d", &Magic); if(Magic < 1 || Magic > 6){ return 0; } do{ fgets(tmp, 255, fin); } while(tmp[0] == '#'); sscanf(tmp, "%d %d", &x, &y); if(x < 1 || y < 1){ return 0; } fgets(tmp, 255, fin); sscanf(tmp, "%d", &level); printf("P%d\n", &Magic); printf("%d %d\n", x, y); printf("%d\n", level); in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in, sizeof(unsigned char), x*y, fin); pixels = (RGB**)malloc(width*sizeof(RGB*)); pixels[0] = (RGB* )malloc(size * sizeof(RGB)); for(i = 1; i < width; i++){ pixels[i] = pixels[i - 1] + height; } free(pixels[0]); for(i = 1; i < width * height * 3; i++){ out[i] = pixels[i][0].r * 0.299 + pixels[i][1].g * 0.587 + pixels[i][2].b * 0.114; } fout = fopen(argv[2], "wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); free(pixels); free(in); free(out); free(fin); free(fout); }

  • mallocがうまく動かない

    コマンドライン引数で指定された文字列を逆順に返すプログラムを作るため 下記のようなプログラムを組みました。 ところが変数strの大きさがargv[1]より大きくなってしまいます。 どうすればよいのでしょうか。 #include <stdio.h> #include <stdlib.h> char *mstrrev (char *s); int main(int argc, char *argv[]){ char *str; str = mstrrev(*(argv+1)); printf("%s",str); free(str); } char *mstrrev (char *s){ int length,i; char *str; for(length=0;*(s+length)!='\0';length++); str = (char *)malloc(sizeof(char)*length); for(i=0;i<length;i++){ str[i] = s[length-1-i]; } return str; }

  • !!の意味がわかりません

    以下のような引数をビット表示するテンプレート関数があったのですが、 !!( val & 1 ) の意味がわかりません。!で反転して!でまた反転したら 元通りになるだけだと思うのですが、 どういう意図でそうなっているのでしょうか? template <typename T> void print_bits ( T val ) { unsigned int n_bits = sizeof ( val ) * CHAR_BIT; for ( unsigned i = 0; i < n_bits; ++i ) { std::cout<< !!( val & 1 ); val >>= 1; } } 強制的に型変換を行っているような気もするのですが、 よく理解できません。 よろしくお願いいたします。

  • 加算できない

    #define NUM 1 void main(int argc, char *argv[]) { int i; float su01[NUM],suetc[NUM],j; FILE *fpi,*fpl; fpi = fopen(argv[1],"r"); fpl = fopen(argv[2],"r"); for(i=0;i<NUM;i++){ fscanf(fpi,"%f",&su01[i]); } for(i=0;i<NUM;i++){ fscanf(fpo,"%f",&suetc[i]); } for(i=0;i<NUM;i++){ suetc[i] += su01[i]; } for(i=0;i<NUM;i++) printf("%f\n",suetc[i]); } このプログラムで「aaa.txt」に入った30と「bbb.txt」に入った20を足して、50が入った「ccc.txt」というファイルを作りたいのですが、足し算をすることが出来ません。 よろしければご指摘をお願いします。

  • ビット演算子を使った処理について

    ビット演算子を使ってビットの内容を変更する処理を教えてください。 プログラムは作ってみたのですが、思い通りの動きをしてくれません。 何かアドバイスをいただけないでしょうか。 #include <stdio.h> int main(void) { int num1 = 0x100000; int k = 0; int cnt = 0; int resval = 0; int cntlvmin = 0; int cntlvmax = 0; int levmin[6]; /* レベル最小値 */ int levmax[6]; /* レベル最大値 */ for(k=0;k<6;k++){ levmin[k] = 30+k*10; levmax[k] = 40+k*10; } /*判定値の設定*/ resval = 67; /* レベル別の範囲判定 */ for(cnt=0;cnt<6;cnt++){ cntlvmin = levmin[cnt]; cntlvmax = levmax[cnt]; /* ビット配列の設定 */ if(val< cntlvmin || cntlvmax<val){ /* 範囲外の場合、右に1つずらす */ num1 = num1 >> 1; } else { break; } } } やりたいことは、ある値(val)が、cntlvmin/cntlvmaxの範囲外の値の場合、num1の値(100000)を右シフトして、(010000)と右へ1つずつずらす。範囲内の場合には処理を終了するといったことです。 よろしくおねがいします。

専門家に質問してみよう