• ベストアンサー

配列のポインタ?

charmer29-2の回答

回答No.4

蛇足ながら。 該当行はこう書き換えた方が判り易そうですね。 if (name[loc][0] == '\0') {   break; } それから、gets()をfgets()に置き換えるなら例えばこうなります。 fgets(name[loc], sizeof(name[loc]), stdin);

noname#168725
質問者

お礼

回答ありがとうございます。 if (name[loc][0] == '\0')は解りやすいですね! fgetsの書き方も教えていただきありがとうございました。

関連するQ&A

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • ポインタ配列

    "one","two","three","four","five","six","seven","eight","nine","ten" のポインタ配列の文字列を、ASCIIコード順に並べ変えようと思ったのですが、 もうどこが間違っているかさえわからないぐらいになってしまいました。 まだまだはじめたばかりなもので、わからないことだらけなんで、 できるだけわかりやすい説明おねがいします。 関数の引数に問題があるのじゃないかと思ったのですが、 何かいいアドバイスありましたら、お願いします。 #include <stdio.h> /* 関数のプロトタイプ宣言 */ int strmp(char *,char *); void cpy(char *,char *); int main (void) { /* ポインタ配列の定義 */ char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"}; /* ポインタのポインタの定義 */ char **pp=x; char k[100]; char *p=k; int i,t,a,b,c,d; a=0; /* ポインタ配列を自作関数を使って、ASCIIコードの大きいほうからに並び替える */ for(i=0;i<9;i++) { for(t=1;t<10;t++) { a=strmp(*(pp+i),*(pp+t)); if(a<0) { cpy(p,*(pp+i) ); cpy(*(pp+i),*(pp+t) ); cpy(*(pp+t),p); } } } for(i=0;i<10;i++) { printf("%s ,",x[i]); } printf("\n"); return 0; } /* 文字の比較をする関数 */ int strmp(char *x,char *y) { int i; for(i=0;*(x+i)==*(y+i);i++) { if( *(x+i)=='\0') { return 0; } } return *(x+i)-*(y+i); } /* 文字をコピーする関数 */ void cpy(char *a,char *b) { int i; for(i=0;*(b+i)!='\0';i++) { *(a+i)=*(b+i); } *(a+i)='\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)

  • ポインタ

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test.txt","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; // printf("%s", bufG); switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } printf("%s", data[2].subject); fclose(fp); return 0; } このプログラムをベースにしてメモリの無駄を省けるような プログラムに修正したいのですが、 ポインタほんとできなくて困ってます。 教えていただいてメモリを取る位置とかは大体わかりました。 まず構造体のメモリをとります。しかしこのままでは固定長になってるので 構造体を少しいじくりますよね。 構造体の中身なのですが typedef struct{ int number; char *class_type; char *name; char *subject; } my; my *data; にして data = malloc(100); このような形でとります。 文字列の型ですがchar *class_typeのようにポインタで宣言しないと bufGを代入して値を入れるときに型が合いませんので 配列にしないのであればポインタ型宣言でいいと思います。 しかしポインタで宣言してstrcpy(・・)の所を data[line].class_type = bufG にするとエラーはでませんが*strの値が変わる度に data[line].class_typeの値が変動するのでdata[line].class_typeが 国語 とかになったりします。 なんかもうさっぱりわからないんですが どうすればいいのでしょうか? 変換したソースがほしいです。

  • 2次元配列とポインタ配列の違い

    2次元配列とポインタ配列の違いを比較するプログラムを作成したつもりなのですが、下のプログラムの printf("we[%d]=%u\n",i,&we[i][0]); という文がどうやら違うらしいのですが、全く分かりません。 なので、なんとなくでも構わないので分かる方がいらっしゃったらお願いします。 #include<stdio.h> int main(void) { int i; char *we[]={"Monday","Tuesday","Wednesday"}; char ek[][10]={"Monday","Tuesday","Wednesday"}; printf("2次元配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("ek[%d]=%u\n",i,&ek[i]); } printf("ポインタ配列のアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i]); } printf("ポインタ配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i][0]); } printf("ポインタ配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("we[%d]=\%s\n",i,we[i]); } printf("2次元配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("ek[%d]=\%s\n",i,ek[i]); } return(0); }

  • ポインタ配列

    ポインタ配列によるひとつのプログラムを組もうと思っています。 で、以下のようなプログラムを作ってみました。 1:#include<stdio.h> 2:#define NUM 5 3:main(void){ 4: char *str[NUM]; 5: int i; 6: for(i=0;i<NUM;i++){ 7: printf("string --->"); 8: scanf("%s",str[i]); 9: } 10: for(i=0;i<NUM;i++){ 11: printf("str[%d] --> %c\n",i,str[i]); 12: } 13:} これなのですが、8行目のscanf文でコンパイルエラーではなく、実行エラーが出ます。どのようにすれば動くようになるのでしょうか? 入力する文字は、9文字以下を想定しています。

  • 文字列を表すための配列とポインタ

    文字列を表すための配列とポインタ  配列とポインタは同様に扱えるもの、と思って、次のプログラムを作りました。処理系は、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;」 と宣言するところが問題のようですが、なぜなのかが分かりません。どなたか、解説をお願いします。

  • ポインタのポインタの必要性

    書物によるとポインタのポインタの使用例として「ポインタの配列」はポインタを使ってアクセスすることができます。」[*]とありますが、どうしてポインタのポインタが必要なのかがいまいちピンと来ません。 どういう場合なのかを知りたく思っています。 [*]サンプルスクリプト ===================================================== char *mnthp[3] = {/* ポインタの配列の宣言 */ "January", "February", "March" }; char **p1;/* 「ポインタのポインタ」の宣言 */ int i, j; p1=mnthp;/* 「ポインタのポインタ」にポインタの配列 */ /* の先頭番地を設定 */ /***** 例1 *****/ for (i = 0; i < 3; i++) {/* 「ポインタのポインタ」の値を変えずに */ printf("%s\n", *(p1 + i));/* 相対的に文字列を出力 */ } ==> このようなことをしなくとも printf("%s", mnthp[i]); で値を参照出来ると思われる。 ===================================================== [*] http://www9.plala.or.jp/sgwr-t/c/sec10-4.html 宜しくお願い致します。

  • 配列とポインタについて

    #include <stdio.h> int main() { char x[3]; char *y; x[0]='a'; x[1]='b'; x[2]='\0'; y="abc"; printf("xの値は%s\n",x); printf("yの値は%s\n",y); } 通常の配列宣言では、このままだと文字列をまとめて 代入できないのに対して、ポインタ変数ならまとめて代入することができるのは何故ですか?そういう仕組みだと言われてしまえば、それまでなんですが・・・

  • 配列とポインタを使って特定の文字だけ大文字にする

    配列とポインタを使って特定の文字だけ大文字にするプログラムを作りたいのですがどのように作ればいいのでしょうか? 例えば、sportsのsだけ判別してSportSというふうにしたいです。 一応以下のようなプログラムを作ったのですが、実行してもsportsのままで何も変わりません・・・。 #include<stdio.h> void mojihenkan(char *); main(void) { char moji[8]={"sports"}; char *p; int i; mojihenkan(moji); p=moji; for(i=0;i<8;i++){ printf("%c",*(p+i)); } return 0; } void mojihenkan(char *a) { int i; for(i=0;i<8;i++){ if(*(a+i)=='s'){ a-32; } } }