• ベストアンサー

get()を否定されました…どのように直せばいいでしょうか…

プログラムで、文中のpikatyuという文字をraityuに変換させるプログラムを作れという問題で、以下のプログラムを作成しました。 すると、警告文で prog.c: In function 'main': prog.c:14: warning: unused variable 'c' prog.c:33: warning: control reaches end of non-void function /var/tmp//cc1HByZn.o(.text+0x51):Infunction 'main': : warning: warning: this program uses gets(), which is unsafe. というものが出てきました。 コンパイルはできるのですが、 講師がgets()を使うなと言うのです。 どのようにすれば認めてもらえるのでしょうか? どこをどのように直せばいいか教えてください。お願いします。 #include<stdio.h> #include<string.h> #define SIZE 512 char *search(char *,char *); void replacce(char *,char *,char *); int main(int argc,char, **argv) { char c; int i = 0, j = 0; char a[SIZE][SIZE]; for (i = 0; i < SIZE; i++) { gets(a[i]); } while(a[j][0] != '\0') { replace(a[j],"pikatyu","raityu"); printf("%s\n", a[j]); j++; } } void replace(char *text, char *key, char *rep) { char *p,buf[SIZE]; p = search(text, key); while(p != NULL) { *p ='\0'; strcpy(buf, p + strlen(key)); strcat(text, rep); strcat(text, buf); p = search (p + strlen(rep), key); } } char *search(char *text, char *key) { int m, n; char *p; m = strlen(text); n = strlen(key); for(p = text; p <= text + m - n; p++) { if(strncmp(p, key, n) == 0) return (p); } return (NULL); }

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

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

fgetsを使ってください。fgetsの使い方がわからない場合は、その旨補足してください。 getsを使うなという理由は、getsを使ったプログラムの場合セキュリティホールが発生し、ハッカー(クラッカー)の攻撃対象となってしまうからです。なぜgetsを使うとセキュリティホールが発生するかは、ここでは説明を割愛しますが、getsが非常に危険な関数であることは、頭にいれておいてください。

train-train-3605
質問者

お礼

お礼が遅くなり、申し訳ありません。無事認めてもらうことができました。本当にありがとうございました。

その他の回答 (1)

  • shidho
  • ベストアンサー率45% (138/303)
回答No.1

宿題だと思いますので、そのものズバリの答えは避けます。 "gets 危険性"といったキーワードで検索してみてください。

関連するQ&A

  • 行が壊れました。1行の長さが2048文字を越えています。

    11行目の""の中の文字数を増やしたいのですが、そのまま増やすと「行が壊れました。1行の長さが2048文字を越えています。」といったメッセージが出てきてしまいます。 ""の中を改行するとエラーになってしまいます。 できることなら""の中を何万文字と増やしていきたいです。 実行結果が欲しいだけなのですが…。 ほとんどこういったものを使ったことがないので、簡単に解決できるのかできないのかすらわかりません。ちなみにMicrosoft Visual c++ 6.0を使用しています。 どうかよろしくお願いします。 [1] #include<stdio.h> [2] #include<string.h> [3] #include <time.h> [4] [5] [6] char *search(char *,char *); [7] [8] int main(void) [9] { [10] [11] static char text[]="あいうえお"; [12] char *p,*key="pen"; [13] [14] clock_t start,end; [15] start = clock(); [16] [17] [18] [19] p=search(text,key); [20] while (p!=NULL) [21] { [22] printf("%s\n",p); [23] p=search(p+strlen(key),key); [24] } [25] end = clock(); [26] printf("%.5f秒かかりました\n",(double)(end-start)/CLOCKS_PER_SEC); [27] return 0; [28] } [29] [30] char *search(char *text,char *key) [31] { [32] int m,n; [33] char *p; [34] [35] m=strlen(text); [36] n=strlen(key); [37] for(p=text;p<=text+m-n;p++) [38] { [39] if(strncmp(p,key,n)==0) [40] return(p); [41] } [42] return(NULL); [43] }

  • ポインタのポインタの使い方

    文字列の途中からの部分を表示させる場合もあって、途中からの 位置というのをcahr**型の配列に記憶させることにしました。 ポインタとnewがよく分からないから、それに近いサンプルを 作って実験しているところです。 #include <iostream.h> main() {  char selected[][6] = {"full", "nomal", "short"};  char *buf;  char **p;  buf = new char[500];  strcpy(buf, ",東京都,千代田区,九段南");  p = new char*[3];  for(unsigned int i=0, j=0; i<strlen(buf); i++)  {   if(buf[i] == ',')p[j++] = &buf[i+1];  }  for(int i=0; i<3; i++)  {   cout << selected[i] << "-" << p[i] << endl;  }  delete [] buf;  delete [] p; } 結果は full-東京都,千代田区,九段南 nomal-千代田区,九段南 short-九段南 で、問題なさそうに見えるけど心配だから質問しました。 このソースに問題はないですか? 得に、 char **p; と p = new char*[3]; と p[j++] = &buf[i+1]; と delete [] buf; が心配です。

  • 動かないです

    おかしなところが有ったらアドバイス・修正等お願いします。 うしろ3行を表示させたいです。 0~2行の場合はその分だけ表示させたいです。 # include <stdio.h> # include <stdlib.h> # include <string.h> char *getline(void) { char *buf = NULL; int size = 0; int oldsize; do { oldsize = size; size = size * 2 + 80; buf = realloc(buf, size + 1); if(!buf) { fprintf(stderr, "memory allocation failed\n"); exit(1); } if(!fgets(buf + oldsize, size + 1 - oldsize, stdin)) if(oldsize) break; else { free(buf); return NULL; } }while(strlen(buf + oldsize) == size - oldsize); return buf; } void scan(char **lines, int n_lines) { char *p; int i; for(i = 0; i < n_lines; i++) lines[i] = NULL; while(p = getline()) { free(lines[0]); for(i = 0; i < n_lines - 1; i++) lines[i] = lines[i+1]; lines[n_lines - 1] = p; } } void print(char **lines, int n_lines) { int i; for(i = 0; i < n_lines; i++) if(lines[i]) fputs(lines[i], stdout); } int main(void) { char *lines[3]; int i; scan(lines, 3); print(lines, 3); for(i = 0; i < 3; i++) free(lines[i]); return 0; }

  • C の文字列置き換え

    #include <stdio.h> // buffer overflowは無視している文字列置き換え関数 void replace(char *buf, char *pre, char *aft) {   char *p;   p = strstr(buf, pre);   if (p){     char *p_2 = p + strlen(pre);     replace(p_2, pre, aft);     memmove(p + strlen(aft), p_2, strlen(p_2)+1);     memcpy(p, aft, strlen(aft));   } } int main(void) {   char buf[1024] = "C:\\programfile\\LOG";   replace(buf, "LOG", "RESULT");   printf("%s\n", buf);   return 0; } というソースが以前出ていたのですがこのバッファーオーバフローはどうすれば回避できるのですか? お願いします

  • ポインタと配列

    次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)

  • C フォームから受け取った知をクッキーで発行 2

    前回 http://okwave.jp/qa/q7765400.html からあれこれしてフォームの値をクッキーに保存できるようになったのですが、バグが出てきました。 一、クッキーが存在しないとエラーが出る ニ、Deta1関数を使って文字列の分解を試みるもうまく分解されない この2つのバグを解決するにはどうしたら直せますか? ---以下ソース--- #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> char *nameset[2],*valueset[2]; char *nameset2[2],*valueset2[2]; int Deta1(char *a,int b); int Dcd(char *set,int a); void get_Form(void); void get_cookie(void); void set_cookie(void); int hen(char *buf, char *mae, char *ato); void Page(int mode); int main(void) { char *nameset[2],*valueset[2]; char *nameset2[2],*valueset2[2]; printf("Content-type: text/html\n"); get_Form(); set_cookie(); get_cookie(); printf("\n"); Page(0); } int Deta1(char *a,int b){ int i=0,cn=0; if(a[0]==NULL){ return(-1); } nameset[0]=a; while((a[++i]!=NULL)&&(i<b)){ /* 項目の分解 */ if(a[i]=='='){ a[i]=NULL; valueset[cn]=a+i+1; } /* データ項目で分解 */ else if(a[i]=='&'){ a[i]=NULL; cn++; nameset[cn]=a+i+1; } } return cn+1; } int Dcd(char *set,int a){ int i,j; char buf,*tmp; if(a==0){ return -1; } tmp=(char*)malloc(a); for(i=0,j=0;i<a;i++,j++){ if(set[i]=='+'){tmp[j]=' ';continue;} if(set[i]!='%'){tmp[j]=set[i];continue;} if(set[++i]>='A'){buf=set[i]-'A'+10;} else{buf=set[i]-'0';} buf*=16; if(set[++i]>='A'){buf+=set[i]-'A'+10;} else{buf+=set[i]-'0';} tmp[j]=buf; } for(i=0;i<j;i++){ set[i]=tmp[i]; } set[i]='\0'; free(tmp); return 0; } void get_Form(void){ int a=0; int i=0; char *chr=NULL; if ( getenv("CONTENT_LENGTH")!=NULL ){ a = atoi( getenv("CONTENT_LENGTH") ); } chr=(char *)malloc(a+1); scanf("%s",chr); chr[a] = '\0'; if (a==0){ return ; } int deta1=Deta1(chr,a); } void get_cookie(void){ int i=0,cn=0; int a=NULL; char *b; if( (getenv("HTTP_COOKIE"))!=NULL){ a=strlen(getenv("HTTP_COOKIE")); } if(a==NULL){ } b=getenv("HTTP_COOKIE"); while((b[++i]!=NULL)&&(i<a)){ if(b[i]=='='){ b[i]=NULL; nameset2[0]=b+i+1; } /* 項目の分解*/ if(b[i]=='-'){ b[i]=NULL; valueset2[cn]=b+i+1; } /*データ項目で分解*/ else if(b[i]=='&'){ b[i]=NULL; cn++; nameset2[cn]=b+i+1; } } for(i=0;i<cn+1;i++){ Dcd(nameset2[i],strlen(nameset2[i])); Dcd(valueset2[i],strlen(valueset2[i])); } } void set_cookie(void) { time_t timer; struct tm *tset; char expires[256]; char *name="sskchat"; int kikan=86400*90; char *set[2]; int i; for(i=0;i<2;i++){ set[i]=NULL; } for(i=0;i<2;i++){ set[i]=valueset[i]; } for(i=0;i<2;i++){ if(set[i]==NULL){ set[i]="no"; } } timer = time(NULL); timer += kikan; tset = gmtime(&timer); strftime(expires, 255, "%a, %d-%b-%Y %H:%M:%S GMT", tset); printf("Set-Cookie:%s=name-%s&mail-%s; expires=%s;\n",name,set[0],set[1],expires); } void Page(int mode){ FILE *fp; char *f1="!name!",*h1; char *f2="!mail!",*h2; if(valueset2[0]==NULL||strcmp("!name!",valueset2[0])==0){ h1=""; } else{ h1=valueset2[0]; } if(valueset2[1]==NULL||strcmp("!mail!",valueset2[1])==0){ h2=""; } else{ h2=valueset2[1]; } char buf[200]; char set[200]; fp = fopen("ren.html", "r+"); while( fgets( set, 200, fp ) != NULL ){ strcpy(buf,set); while(hen(buf, f1, h1)); while(hen(buf, f2, h2)); printf("%s", buf); } fclose(fp); } int hen(char *buf, char *mae, char *ato){ char *nw; size_t zen,go; zen = strlen(mae); go = strlen(ato); if(zen == 0 || (nw = strstr(buf, mae)) == NULL){ return 0; } memmove(nw + go, nw + zen, strlen(buf) - (nw + zen - buf ) + 1); memcpy(nw, ato, go); return 1; } ---ソースここまで--- ---ren.htmlの内容--- <form action="first.exe" method="post"> 名前:<input type="text" name="name" size="100" value="!name!"><br><br> メール:<input type="text" name="mail" size="100" value="!mail!"><br><br> 本文:<textarea name="text" cols="70" rows="10"></textarea><br><br> <input type="submit" value=" 送 信 "><br> </form>

    • ベストアンサー
    • CGI
  • 配列のコピー

    配列bufの内容をstrにコピーしてgetsを使い 表示させたいのですが、うまくいかず 余計な文字まで出力されます、どのようにすれば うまくいくでしょうか? どなたかアドバイスよろしくお願いしますm(_ _)m #include <stdio.h> void main(){ char buf[256]="message"; char str[256]; int i = 0; while(buf[i] != NULL){ str[i] = buf[i]; i++; } printf(str); }

  • 強制終了されていまいます。

    標準入力された1行を"<"から">"までと文字のところにわけるプログラムを書いたのですが、コンパイルして実行して入力すると、画面が黒くなって止まってしまいます。以下のところが問題の部分だと思うんですが、理由がわかりません。よろしくお願いします。 while(fgets(buf, 1024, stdin) != NULL){ i = 0; j = 0; while(buf[i] != '\n' || buf[i] != '\0'){ if ((x = (char *)malloc(sizeof(char))) == NULL){ printf("malloc error\n"); exit(1); } if(buf[i] == '<'){ j = i; while(buf[j] != '>'){ j++; } strncpy(x, &buf[i], j-i+1); i = j + 1; x[strlen(x)] = '\0' putRear(deq, x); } else if(isalpha(buf[i])){ j = i; while(buf[j] != '>'){ j++; } strncpy(x, &buf[i], j-i); i = j + 1; x[strlen(x)] = '\0'; putRear(deq, x); } } }

  • ソケット通信で大容量のメールの場合送信されません

    質問です smtpクライアントからtcpでメール送信するプログラムを組んだのですが、 添付ファイルのサイズが大きいもの(500000行を超えるような)を1行ずつsendメソッドで送信すると送信先で受信できません。 400000行まではいくのですが… sendではエラーは返っておらずパケットは送られてる様です。 パケットダンプをとってみたのですが、メールサーバから応答は返ってきていました。 filein.open("test.eml"); if (filein.fail()){ return -1; } if((soc = ConnectHost("testhost","smtp",25)) == -1){ return -1; } send_buf = new char[BUFSIZ]; sprintf(send_buf,"MAIL FROM:<%s>\r\n","test@test.test"); SocketSend(soc,send_buf,strlen(send_buf)); sprintf(send_buf,"RCPT TO:<%s>\r\n","test2@test.test"); SocketSend(soc,send_buf,strlen(send_buf)); sprintf(send_buf,"DATA\r\n"); SocketSend(soc,send_buf,strlen(send_buf)); ss = new char[1024]; while (filein.getline(ss,1024)){ sprintf(send_buf,"%s\r\n",ss); SocketSend(soc,send_buf,strlen(send_buf)); ←ここでループ } delete ss; sprintf(send_buf,"\r\n.\r\n"); SocketSend(soc,send_buf,strlen(send_buf)); SocketRead(soc,send_buf); delete send_buf; filein.close(); if(SocketClose(soc) == -1){ return err; } int SocketSend(int soc,char* buff,int nbytes) { register int nleft,nwritten; char* p = buff; nleft = nbytes; while(nleft > 0) { nwritten = send(soc,p,nleft,0); if(nwritten <= 0){ return nwritten; } nleft -= nwritten; p += nwritten; } return 0; } int SocketClose(int soc) { int ret; if(close(soc) == -1){ return -1; } return 0; } int SocketRead(int soc,char* buff) { int rbyte; rbyte = read(soc,buff,strlen(buff)); return 0; } 上記で問題になっていそうなところがあれば 教えてください。。 よろしくお願いします。

  • ファイルの置換

    ファイルを置換するプログラムを作ったのですがうまく置換してくれません。コードは以下のように書きました。(コンパイラは出来ました) #include <stdio.h> #include <stdlib.h> #include <string.h> #define FALSE 0 #define TRUE 1 main() { FILE *fp; char filename[256]; FILE *outfp; char outfilename[256]; char key[128]; char str[128]; char c; int p; int keylen; int i=0 ; int search=FALSE; int count =0; printf(" enter filename"); scanf("%s",filename); printf("seach word"); scanf("%s",key); keylen=strlen(key); printf("change word"); scanf("%s",str); if((fp=fopen(filename,"r"))==NULL) { printf("file open error"); exit(1); } strcpy(outfilename,filename); strcat(outfilename,"_"); if((outfp=fopen(outfilename,"w"))==NULL) { printf("file open error"); exit(1); } while((c=fgetc(fp))!=EOF) { if(search) { if(c != key[i]) { search=FALSE; for(p=0;p<i;p++) { fputc(key[p],outfp); } fputc(c,outfp); i=0; } else{i++;} } else { if(c==key[i]) {search=TRUE;i++;} else {fputc(c,outfp);} } if (keylen==i) { count++; fputs(str,outfp); search=FALSE; i=0; } } fclose(fp); fclose(outfp); printf("apperance number %d\n",count); return 0; } どこか間違っていますか?教えてください。

専門家に質問してみよう