C言語ファイルの意味と文字列の検索方法

このQ&Aのポイント
  • C言語ファイルの意味と、文字列の検索方法についてご教示ください。
  • プログラム中でword3とword4に対してポインタを使用する理由を教えてください。
  • word4 = strchr(word4, *word2)のようなポインタ指定している箇所の意味は何ですか?
回答を見る
  • ベストアンサー

C言語 ファイルの意味

C言語 文字列で分からない部分があるのでご教示お願いします。 内容は「文字列の検索」です。 #include<stdio.h> #include<string.h> int main(void) { char word[] = "abcabdabe"; char word2[] = "abd"; char *word3 = "ABD"; char *word4 = NULL; printf("処理前の文字列:%s\n", word); word4 = word; word4 = strchr(word4, *word2); while (word4 != NULL){ printf("'a'が見つかった場所からの文字列: %s<\n", word4); if (strncmp(word4, word2, strlen(word2)) == 0) { strncpy(word4, word3, strlen(word3)); } word4 += 1; word4 = strchr(word4, *word2); } printf("処理後のword4: %s\n", word); return 0; } このプログラムの場合、word3とword4ではなぜ、*word3, *word4とポインタで設定するのでしょうか? また、「word4 = strchr(word4, *word2)」と *word2のようにlここでポインタ指定するのは何故なのでしょうか?

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

  • ベストアンサー
  • hashioogi
  • ベストアンサー率25% (102/404)
回答No.1

[Q1]word3とword4ではなぜ、*word3, *word4とポインタで設定するのでしょうか? [A1]別にchar word3 [] = "ABD";としても問題はないと思います。気まぐれとしか思えません。 [Q2]「word4 = strchr(word4, *word2)」とポインタ指定するのは何故か? [A2] ポインタ指定なんかしていない。ポインタが指している実体を引数にしている。 char a = 'A' ; char *pa ; pa = &a ; char c ; のような場合、'A'をアクセスする場合には c = *pa ; と書くでしょ ? それと同じです。 つまり、 word4 = strchr(word4, *word2) は word4 = strchr(word4, 'a') と同じです。

関連するQ&A

  • C言語の問題

    選んだファイルのデータを読み取り、そのファイルのデータの中の文字列を数えるプログラム(例えば、「I like sport」 だったら3ワード)を作りたいのですが、文字数を数えるものしかわからないです。 一応、下のプログラムが文字数を数えるものですが、どうすれば文字列を数えるものになりますでしょうか?教えてください。 #include <stdio.h> #include <string.h> #include <stdlib.h> main() { FILE *fin; char filename[20]; char data[256]; int n; printf("ファイル名の入力 :"); gets(filename); fin=fopen(filename,"r"); if(fin == NULL){ printf("%sがオープンできません!\n",filename); exit(1); } while(fgets(data,256,fin) !=NULL){ } n=strlen(data); printf("ファイル %s には、%dワードがあります。\n",filename,n); fclose(fin); }

  • C言語 文字列操作

    トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか? ~~~~以下ソース~~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> char *Trim(char *str); char *Remove(char *str, char *rmv); void main(void) {  char str[10], rmv[10], *p;  int c;  /* " abcd "をトリムする */  strcpy(str, " abcd ");  printf("トリム前 |%s|\n", str);  p = Trim(str);  printf("トリム後 |%s|\n", str);  /* 指定文字列を削除する */  printf("削除する文字列を入力してください :");  scanf("%s", rmv);  Remove(str, rmv);  printf("削除後 |%s|\n", str);  exit(0); } char *Trim(char *str) {  char space[] = " ";  char null[] = "";  int index = 0;  while(1){   if(strcmp(&(str[index]), null) == 0){    index--;    if(strncmp(&(str[index]), space, 1) == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     break;    }   }else{    if(strncmp(&(str[index]), space, 1) == 0 && index == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     index++;    }   }  }  return str; } char *Remove(char *str, char *rmv) {  int c, size, i;  char *p;  c = '\0';  p = strchr(rmv, c);  size = p - rmv;  for(i = 0; i < size; i++){   c = (int)rmv[i];   p = strchr(str, c);   if (p != NULL) {    strcpy(&(str[p-str]), p + 1);   }   else{    printf("""%c""は見つかりませんでした\n", c);   }  }  return str; }

  • C言語の文字列の取り扱いが分かりません

    こんにちは。 C言語で分からないことがあり、質問させていただきました。 学校で、文字列の取り扱いを習いました。 そこで質問なんですが、以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書くことってできないですか? 先生に質問したところ、ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?もしよろしければお願いします。 以下のプログラムですが、ユーザーから2つの文字列を受けて、そこから4つの文字列関数を使ってみましょう、というやつです。実行結果も貼っておきますね。 #include <string.h> #include <stdio.h> int main(void) { char str1[80], str2[80]; int i; printf("INPUT 1st word-line. : "); gets(str1); printf("INPUT 2nd word-line. : "); gets(str2); /*文字列(word-line)の長さを確認します。*/ printf("%s is %d moji long.\n", str1, strlen(str1)); printf("%s is %d moji long.\n", str2, strlen(str2)); /*文字列を比較します。*/ i = strcmp(str1, str2); if (!i) printf("two word-lines are same length.\n"); else if (i < 0) printf("%s is smaller than %s.\n", str1, str2); else printf("%s is bigger than %s.\n", str1, str2); /*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/ if((strlen(str1) + strlen(str2)) < 80 ){ strcat(str1, str2); printf("%s\n", str1); } /*str2をstr1にコピーする*/ strcpy(str1, str2); printf("%s %s\n", str1, str2);

  • C言語に詳しい方お願い致しいます

    文字列Aから文字列Bを除いた結果を表示するプログラムなのですが 一ヶ所分からない部分があります。 #include <stdio.h> #include <string.h> int main(void){  char str1[] = "abcdefg";  char str2[] = "cde";  char str3[128] = "";  char *p1 = str1, *p2;  size_t len;  len = strlen(str2);  while((p2 = strstr(p1,str2)) != NULL) {   strncat(str3,p1,p2 - p1);   p1 = p2 + len;   printf("----\n");   printf("p2=%s\n", p2);   printf("str3=%s\n", str3);   printf("p1=%s\n", p1);  }  strcat(str3,p1);  printf("%s\n",str3);  return 0; } while文中の p1 = p2 + len; なのですが、何故これでp1の内容が「fg」になるのでしょう。

  • C言語でファイルから特定の文字を抽出

    現在C言語でプログラム開発しています。 文字列が並んだテキストファイルから特定の部分のみを抽出したいのですが、うまくいきません。 お力を貸していただけないでしょうか。 テキストファイルの構造はこんな感じです。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 文字列 文字列 文字列badresult=*****文字列badresult=*****文字列badresult=*****文字列result=***** ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー これが10セット程記述されたファイルです。 ここから全てのbadresultの数値とresultの数値を抽出したいのです。 私が現段階で作成したプログラムがこちらです。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXLINE 2084 int main(void){ FILE *fp; char line[MAXLINE]; char s1[]="badresult"; char s2[]="result="; char *r; if ((fp = fopen( "テキストファイルへのダイレクトパス", "r" )) == NULL){ printf("エラーメッセージB\n"); exit(1); } while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line,s1)!=NULL){ printf("%.27s",strstr(line, s1),"\n"); printf(" "); printf(strstr(line, s2)); } } } ですがこれだと1行に全てのbadresultが含まれているため、結果は ----------------------------- badresult=***** result=****** ----------------------------- とbadresultは1つしか出てきません。 strstrのポインタをどうにかできないかと考えたのですが、 私のC言語の知識も浅いためなかなかうまくできません。 Cプログラミングに精通している方、どうか改善策を教えていただけないでしょうか。 できればなるべく簡単な方法ですと助かります。

  • C++の問題で困っています。

    C++の問題で困っています。 今,C++の入門書を読んでその中の演習問題に取り組んでいるのですが、この本には答えがついていないみたいなので、問題で悩んでいます。 お力を貸してください。 問題 「文字列 s に含まれる最も先頭に位置する文字 c へのポインタを返す関数 strchr_ptr を作成せよ。型は char * strchr_ptr(const char *s, char c); とする。例えば、文字列 s が "ABSZXYX" で文字 c が 'X' であれば、返却するのは &s[4]である。 なお、文字 c が文字列 s に含まれない場合は NULL を返却すること。 」 です。 僕はこの問題に対して、以下のように答えました。 ヘッダのインクルードなどは省きます。 char *strchr_ptr(const char *s, char c) {         for(int i = 0; s[i]; i++)         if(s[i] == c)             return const_cast<char *>(&s[i]);     return NULL; } int main() {     char s[36] = "ABSZXYX";     cout << strchr_ptr(s, 'X') << "\n";     cout << &s + 4 << "\n"; } と書きました。 cout << &s + 4 << "\n"; はこの上の文で導き出したアドレスがあっているか確かめるものです。 ですが、これをコンパイルして実行すると、 ----------------- XYX 0012FFE0 ----------------- となり、関数側のほうはアドレス的な表記をしてくれません・・。 どうにかして、アドレス表記にしようとあれこれ考えたのですが、どうしても出来ませんでした。 どのようにしたらいいのか教えてください。 初歩的な質問ですが、よろしくお願いします。

  • c 言語初心者です。

    c 言語初心者です。 私は下記の構造体配列をつくりました。 しかしバッファオーバーランが起きてエラーが起きてしまいます。 ヒープ領域に問題があるのかもしれませんが、プログラム上どこに原因があるのかが良くわかりません。 どなたかよろしければ教えていただけないでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include<memory.h> struct s { int i; char name[25]; char huri[25]; char num[23]; }; void touroku(struct s *p); void hyouji(struct s *p); int main(void) { struct s data; touroku( &data ); hyouji( &data ); //data.num *= 1; /* dataはポインタではないのでドット演算子 */ hyouji( &data ); return 0; } /* 構造体のメンバを設定する */ void touroku(struct s *p) { int i=0; for(i=1;i<3;i++) { printf( "25文字以内の名前を入力して下さい\n" ); memset(p[i].name, 0, sizeof(p[i].name)); fgets( p[i].name,sizeof(p[i].name) , stdin ); if(strchr(p[i].name,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].name[strlen(p[i].name)-1]=='\n')//改行解除 { p[i].name[strlen(p[i].name)-1] = '\0'; } printf("25文字以内のふりがなを入力してください\n"); memset(p[i].huri, 0, sizeof(p[i].huri)); fgets(p[i].huri,sizeof(p[i].huri),stdin); if(strchr(p[i].huri,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].huri[strlen(p[i].huri)-1]=='\n')//改行解除 { p[i].huri[strlen(p[i].huri)-1] = '\0'; } printf( "整数を入力して下さい\n" ); memset(p[i].num, 0, sizeof(p[i].num)); fgets(p[i].num,sizeof(p[i].num),stdin ); if(strchr(p[i].num,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].num[strlen(p[i].num)-1]=='\n')//改行解除 { p[i].num[strlen(p[i].num)-1] = '\0'; } } } /* 構造体のメンバを出力する */ void hyouji(struct s *p) { int i=0; for(i=1;i<3;i++) printf("%-8s %3s %3s %d\n" ,p[i].name , p[i].huri , p[i].num , i); puts("----------------------------------------------------------------"); return ; }

  • C言語で分からないところがあるのですが

    すみません。C言語のポインタで分からないことがあって来ました。 ポインタの理屈は理解してはいるのですが、いざソースコードを書いてみようということになると全く手がつけられずにいます。 以下のソースコードですが、strlen()と同じ働きをする関数mystrlen()と、strcmp()と同じ働きをする関数mystrcmpを、ポインタを使って作成するものです。どこをどうすればいいのか教えてくださいませんか。 #include <stdio.h> int main(void) { char str1[80], str2[80]; int i, j; int len1, len2; printf("第1の文字列を入力してください: "); gets(str1); printf("第2の文字列を入力してください: "); gets(str2); /* * 文字列の長さを確認する */ /* NULL文字(文字列の最後)まで読み飛ばす */ for (len1 = 0; len1 < 80 && str1[len1] != '\0'; len1++) ; /* ループ終了後、len1 に文字列の長さが入っている */ if (len1 < 80) { printf("%s は %d 文字の長さです\n", str1, len1); } else { printf ("第1の文字列が80字以上あります\n"); } /* str2 についても同様 */ for (len2 = 0; len2 < 80 && str2[len2] != '\0'; len2++) ; if (len2 < 80) { printf("%s は %d 文字の長さです\n", str2, len2); } else { printf ("第2の文字列が80字以上あります\n"); } if (len1 < 80 && len2 < 80) { for (i = 0; i < 80 && str1[i] != '\0' && str2[i] != '\0' && str1[i] == str2[i]; i++) ; if (str1[i] == str2[i]) { /* 両者同時に == '\0' のはず*/ printf("文字列は等しい\n"); } else if (str1[i] < str2[i]) { /* str1[i] == '\0' のはず*/ printf("%s は %s より小さい\n", str1, str2); } else { /* str2[i] == '\0' のはず*/ printf("%s は %s より大きい\n", str1, str2); } } /* * 十分なスペースがあれば、str2をstr1の最後に連結する */ if (len1 + len2 < 80) { /* str1 の末尾を探す */ for (i = 0; str1[i] != '\0'; i++) ; /* ループを抜けた段階では i は len1 と同じはずなので、 上記のループを作らず、i の代わりに len1 を用いるのも可 */ /* それ以降に str2 の中身をコピーする */ for (j = 0; str2[j] != '\0'; j++) { str1[i+j] = str2[j]; } str1[i+j] = '\0'; printf("%s\n", str1); } else { printf ("文字列をつなげた長さが80字以上あります\n"); } /* * str2をstr1にコピーする */ if (len1 + len2 < 80) { for (i = 0; str1[i] != '\0'; i++) { str1[i] = str2[i]; } str1[i] = '\0'; printf("%s %s\n", str1, str2); } return 0; }

  • C言語について

    以下のプログラムについて alice.txtからテキストを読み込みその中の異なる単語の数を求めるプログラムです #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stddef.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(int); void all_words(void); FILE *fp, *fp2; char *fn="alice.txt"; char *fn2="total word.txt"; const char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x=0, c, l, t=0; char word3[LMAX][NMAX]; char word1[NMAX]; char word2[NMAX]; char *tp; char *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); return -1; } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); return -1; } for(c=0;c<LMAX;c++){ if(fgets(word3[c],NMAX,fp)==NULL) break; p++; } for(c=0;c<p;c++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(word3[c][x]); } tp=word1; while((tp2=(char*)strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`'){ t=1; } tp2++; } strcpy(word2,tp2); l=strlen(word2)-1; if(word2[l]=='\''){ word2[l]='\0'; } if(word2[l]==l){ word2[l]='\0'; } if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(); return 0; } void all_words(void){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); return; } for(;;){ if(fgets(word3, NMAX,fp2)==NULL){ break; } n++; } fclose(fp2); count(n); } void count(int n){ int c, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp; char *yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); free(m); return; } for(c=0,xp=m; c<n;c++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); c=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; c++; } else{ c=1; } } printf("%d\n",n-y); free(m); fclose(fp2); } このプログラムを実行するとメモリリークになってしまうのですが 確保していないメモリ領域に代入しているのが原因らしいのですが いろいろ試してみたのですがメモリリークが直りません どうしたらよいでしょうか? よろしくお願いします

  • C言語について

    以下のプログラムについて alice.txtからテキストを読み込みその中の異なる単語の数を求めるプログラムです #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stddef.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(int); void all_words(void); FILE *fp, *fp2; char *fn="alice.txt"; char *fn2="total word.txt"; const char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x=0, c, l, t=0; char word3[LMAX][NMAX]; char word1[NMAX]; char word2[NMAX]; char *tp; char *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); return -1; } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); return -1; } for(c=0;c<LMAX;c++){ if(fgets(word3[c],NMAX,fp)==NULL) break; p++; } for(c=0;c<p;c++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(word3[c][x]); } tp=word1; while((tp2=(char*)strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`'){ t=1; } tp2++; } strcpy(word2,tp2); l=strlen(word2)-1; if(word2[l]=='\''){ word2[l]='\0'; } if(word2[l]==l){ word2[l]='\0'; } if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(); return 0; } void all_words(void){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); return; } for(;;){ if(fgets(word3, NMAX,fp2)==NULL){ break; } n++; } fclose(fp2); count(n); } void count(int n){ int c, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp; char *yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); free(m); return; } for(c=0,xp=m; c<n;c++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); c=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; c++; } else{ c=1; } } printf("%d\n",n-y); free(m); fclose(fp2); } このプログラムを実行するとメモリリークになってしまうのですが 確保していないメモリ領域に代入しているのが原因らしいのですが いろいろ試してみたのですがメモリリークが直りません どうしたらよいでしょうか? よろしくお願いします

専門家に質問してみよう