文字列の探索プログラムの改良方法
- C言語で作成した文字列探索プログラムの改良方法を教えてください
- コンパイル時の警告「問題のあるポインタの変換(関数 main)」について解決策を教えてください
- ファイルを指定して文字列を探索するプログラムを作成しましたが、うまく動かないときの改良方法を教えてください
- ベストアンサー
文字列の探索
ファイル名を指定して文字列の探索を行うというプログラムをC言語で作成したのですが、 コンパイルのときに警告で「問題のあるポインタの変換(関数 main )」と出て、うまい具合に動きません。改良点を教えてください。 #include<stdio.h> #include<string.h> #include<stdlib.h> unsigned char *s1; unsigned char *s2; unsigned char *cp; FILE *fp; char fname[64]; void TestStrStr(void); main(){ s1 = calloc(256, sizeof(unsigned char)); s2 = calloc(256, sizeof(unsigned char)); printf("Input Filename..."); scanf("%s",fname); while(1){ fp = fopen(fname, "r"); if(fp == NULL){ printf("ファイルを開くことができません...\n"); printf("Input Filename..."); scanf("%s",fname); }else break; } s1=fp; // printf("文字列1を入力してください:"); // scanf("%s",s1); printf("文字列2を入力してください:"); scanf("%s",s2); TestStrStr(); return 0; } void TestStrStr(void){ cp = strstr(s1, s2); if(cp == NULL) printf("'%s'に'%s'のいずれの文字も含まれない.\n", s1, s2); else printf("'%s'の中に現れる'%s'という文字列は%d文字目にある.\n", s1, s2, cp - s1 + 1); free(s1); free(s2); }
- blackcat-1983
- お礼率4% (5/109)
- C・C++・C#
- 回答数3
- ありがとう数2
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#include <stdio.h> #include <stdlib.h> #include <string.h> char* s1; char* s2; char* cp; FILE* fp; char fname[64]; void TsetStrStr(void); int main(void) { s1 = (char*)calloc(256, sizeof(char)); s2 = (char*)calloc(256, sizeof(char)); printf("Input Filename..."); fgets(fname, 64, stdin); while(1){ fname[strlen(fname)-1] = '\0'; fp = fopen(fname, "r"); if(fp == NULL){ printf("ファイルを開くことができません...\n"); printf("Input Filename..."); fgets(fname, 64, stdin); }else break; } fgets(s1, 256, fp); fclose(fp); printf("文字列2を入力してください:"); fgets(s2, 256, stdin); s2[strlen(s2)-1] = '\0'; TsetStrStr(); (void)getchar(); return 0; } void TsetStrStr(void) { cp = strstr(s1, s2); if(cp == NULL) printf("'%s'に'%s'のいずれの文字も含まれない.\n", s1, s2); else printf("'%s'の中に現れる'%s'という文字列は%d文字目にある.\n", s1, s2, cp - s1 + 1); free(s1); free(s2); } scanfは基本的にお勧めできないので、 全てfgetsで統一しました。 後、グローバル変数もどうでしょうか? 関数にポインタで渡されては?
その他の回答 (2)
- ret
- ベストアンサー率40% (8/20)
問題点 1 calloc の戻り値を明示的にキャストする必要あり 2 s1 = fp; unsigned char* に ファイルポインタを入れようとしている。 fscanf(), fread() で読み込んで処理 (fclose()を忘れずに (この場合mainを抜けるので不要かも知れないが、 癖をつける意味で…)) 3 strstrに対し、unsigned charを使っている char配列に変更 以上を気をつけてください。
- liar_adan
- ベストアンサー率48% (730/1515)
まんなかよりやや下にある > s1=fp; というところが無茶です。 ファイルを読み込みたかったのかもしれませんが、 これでは読み込めません。 ファイルの内容を文字列として読み出すには、 fgets()などの標準関数を使います。 使い方は、説明すると煩雑になるし、 教科書には必ず書いてあるのでそっちを見てください。
関連するQ&A
- ある行が探索できない
すいませんが、前回同じような質問をしましたが、再度質問します。文字列の探索で、 printf("Input Filename..."); scanf("%s",fname); while(1){ fp = fopen(fname, "r"); if(fp == NULL){ printf("ファイルを開くことができません...\n"); printf("Input Filename..."); scanf("%s",fname); }else break; } // fscanf(fp,"%s",fname); //1行目以外のみ可能 // fread(s1, 1000, 1000, fp); //上記 // s1 = fgetc(fp); fgets(s1, 10000, fp); //1行目のみ可能 // s1 = fscanf(fp); // s1=fp; // printf("文字列1を入力してください:"); // scanf("%s",s1); printf("文字列2を入力してください:"); scanf("%s",s2); cp = strstr(s1, s2); if(cp == NULL) printf("%sに%sのいずれの文字も含まれない.\n", s1, s2); else printf("%sの中に現れる%sという文字列は%d文字目にある.\n", s1, s2, cp - s1 + 1); free(s1); free(s2); というプログラムを作ったのですが、仮に3行のテキストファイルを読み込ませると、コメントの通り、 fscanf(fp,"%s",fname); //1行目以外のみ可能 fread(s1, 1000, 1000, fp); //上記 とすると、2,3行目のみが探索出来て、 fgets(s1, 10000, fp); //1行目のみ可能 とすると、1行目のみが探索可能になっています。 すべての行を探索可能にするにはどうすれば良いか教えてください。
- ベストアンサー
- C・C++・C#
- 文字列のコピー
C言語で、文字列をコピーする関数で、処理が止まってしまいます。 以下が実行したプログラムです。 #include<stdio.h> #include<string.h> void copy(char *str2 ,char *str3){ strcpy(str2,str3); } void input(char* str){ scanf("%s",str); } int main (void){ char *a; char *b="TEST"; printf("%s\n",b); input(a); copy(b,a); printf("%s",b); return(0);} copy(b,a);で処理が止まってしまいます。入力した文字列を表示できるように、御指摘お願いします。
- 締切済み
- 情報工学
- 文字列を表すための配列とポインタ
文字列を表すための配列とポインタ 配列とポインタは同様に扱えるもの、と思って、次のプログラムを作りました。処理系は、Visual Studio 2010 コマンドプロンプトです。 #include <stdio.h> void main(void) { char a[256]; char *b; printf("文字列を入力してください。\n"); printf("例「abcde」\n\n"); printf("配列型文字列を使います。\n"); scanf("%s", a); printf("文字列は%sです。\n\n", a); printf("ポインタ型文字列を使います。\n"); scanf("%s", b); printf("文字列は%sです。\n", b); } すると、まずコンパイル時に、 「warning C4700: 初期化されていないローカル変数'b'が使用されます」 と表示されました。そして、実行すると、「配列型文字列」の方は問題ないのですが、「ポインタ型文字列」の方の実行後に、 「x.exeは動作を停止しました。 問題が発生したため、プログラムが正しく動作しなくなりま した。プログラムは閉じられ、解決策がある場合は Windowsから通知されます。」 と表示され、エラーとして終了してしまいます。 「char *b;」 と宣言するところが問題のようですが、なぜなのかが分かりません。どなたか、解説をお願いします。
- ベストアンサー
- C・C++・C#
- ファイルから文字列を読み出して16進数に変換
test1.txtというファイルから文字列を読み出して16進数に変換、という処理をしたいのですがうまくいきません。どこがどう悪いのでしょうか?ご教授のほどお願いします。 ---------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE *fp; char *fname = "test1.txt"; char str[100]; int num; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%s is not open.\n", fname ); return -1; } while( fgets(str, 100, fp ) != NULL ){ num = strtol(str, NULL, 16); printf( "%s", str ); printf("%x\n", num); //ここでうまく出力されません } fclose( fp ); return 0; } ---------------- ちなみに、test1.txtの中身は以下のようになってます。 44DB4147E6075A92E878EB68C44DD51F 5DCE86622D846BF272215A792AF31A3E 46FF69A29D3DF1D4842461B239256C26
- ベストアンサー
- C・C++・C#
- どうやってフローチャートを書きますか
#include<stdio.h> void main() { FILE*fp; char buf[128]; char *rc; char fname[20]; do{ printf("file name>>>"); scanf("%s",fname); fp=fopen(fname,"r"); if=(fp==NULL) printf("File Open Err¥n"); }while(fp==NULL); rc=fgets(buf,128,fp); while(rc!=NULL){ printf("%s",buf); rc=fgets(buf,123,fp); } fclose(fp); }
- 締切済み
- C・C++・C#
- 配列やポインタに文字列を設定することについて
◎1------------------------- #include<stdio.h> int main(void) { char ss[80]; scanf("%s",ss); printf("%s\n",ss); return 0; } ---------------------------- ◎2--------------------------- #include<stdio.h> int main(void) { char *ss="abcde"; printf("%s\n",ss); return 0; } ------------------------- ◎3---------------------- #include<stdio.h> int main(void) { char *ss; ss="abcde"; printf("%s\n",ss); return 0; } ------------------------- 以上3つプログラムで疑問をいだいたのですが、 まず◎1で、これは例えば、 cahr ss[80]="abc"; のように配列ssに文字列"abc"そのものを入れているのか、 char *ss="xyz"; のようにまず"xyz"という文字列をメモリ上のどこかに設定し、その先頭番地をssに代入しているのか、どちらの考えでいいのかわかりません。 次に、◎2、3ではどちらも正常に実行できたのですが、特に◎3で「ss="abcde";」と記述していますが、ssにはアドレスを代入するという認識かあるのですが、文字列定数を代入しても問題ないのか?という疑問があります。 教えていただけたら嬉しいです。
- ベストアンサー
- C・C++・C#
- 文字列
下のプログラムは何をするためのプログラムなのか教えてください。 個人的にはJISコードに関係していると思うのですがさっぱりわかりません。 どなたか詳しい説明お願いします。 #include <stdio.h> #define LEN 255 int main(void) { char str[LEN]; char cipher[LEN]; int ikey; int i,n; printf("文字列を入力せよ : "); scanf("%s", str); printf("鍵を入力 : "); scanf("%d", &ikey); i = 0; while (str[i]!='\0') { n = (str[i]-'A'+ikey)%26; cipher[i] = 'A'+n; ++i; } cipher[i] = '\0'; printf("%s\n", cipher); return 0; }
- ベストアンサー
- C・C++・C#
- ファイルから一文字ずつ読み込む
ファイルを読み込むfgetc()関数のところでプログラムが停止します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char name[],int a){ printf("ファイル名を入力してください。\n"); scanf("%s",name); } void open(FILE *fp2,char name[]){ if((fp2=fopen(name,"r"))==NULL){ printf("ファイルオープンエラー"); } } int count(FILE *fp3){ int ch=0; int count=0; if(fp3==NULL){ printf("error"); } while((ch=fgetc(fp3))!=EOF){ if(ch=='\n'){ count++; } } printf("TEST"); fclose(fp3); return(count); } int main (void){ FILE *fp; char fname[30]; get_name(fname,30); open(fp,fname); printf("%d",count(fp)); return(0);} ファイル名を入力してください。ファイル名を入力、プログラム停止です。 '\n'を数えれるようにしてください。御指摘お願いします。
- 締切済み
- 情報工学
- 多元配列について(ANSI C)
動的多元配列で、 Voidポインタに、多種の型がぶら下がった多元配列を作り、 読み書きをしたいのですがどのようにしたらよろしいでしょうか。 具体的には、 x[0][1]は、intで「2」が入っている x[0][4]は、intで「9」が入っている x[1][2]は、charでしかも文字列の配列で「goo」が入っている x[1][5]は、charでしかも文字列の配列で「教えて」が入っている x[0]は、int型の配列。X[1]は、文字列型の配列。 というようなものです。 一応ソースは作ってみたのですが、int型では問題なくいくのですが、 文字列は、コンパイルはできますが、実行すると予期せぬことが起きます。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { void **topPointa; int * iDataInput; int * iDataOutput ; char * chDataInput; char * chDataInput2; char * chDataOutput1 ; // ポインタアドレス用のメモリ確保 topPointa = (void *) calloc (10 , sizeof(void *)); if(topPointa == NULL) { printf("メモリが確保できません\n"); exit(-1); } //int配列のメモリ確保 iDataInput = (int * ) calloc (10 , sizeof(int)); if(iDataInput == NULL) { printf("メモリが確保できません\n"); exit(-1); } iDataInput[0] = 3 ; iDataInput[1] = 4 ; topPointa[0] = (void * ) &iDataInput; //int配列の取り出し iDataOutput = *(int *) topPointa[0]; printf( "int: %d\n", iDataOutput[0] ); printf( "int: %d\n", iDataOutput[1] ); //char配列 のメモリ確保 chDataInput = (char * ) calloc (10 , sizeof(char *)); if(chDataInput == NULL) { printf("メモリが確保できません\n"); exit(-1); } chDataInput2 = (char * ) calloc (10 , sizeof(char)); if(chDataInput2 == NULL) { printf("メモリが確保できません\n"); exit(-1); } strcpy(chDataInput2 , "hoe"); chDataInput[0] = &chDataInput2; topPointa[1] = (void * ) &chDataInput; //char配列の取り出し chDataOutput1 = *(char *) topPointa[1]; printf( "char: %S\n", chDataOutput1[0] ); free(iDataInput); free(chDataInput); free(chDataInput2); return 0; } 言語は、C言語ANCI Cでお願いします。 以上。よろしくお願いします。
- ベストアンサー
- C・C++・C#
補足
ありがとうございます。 訂正例を教えて下さるとうれしいです。