ポインタ
ポインタ
今、ポインタの問題をやっているのですが、エラーが出てどう対処すればよいのか分からないので教えてください。
最大5人の名前を格納するポインタ配列(例:char *name[5])を宣言する。
キーボードから一人ずつ名前を入力し、その名前の文字列を格納できる領域を確保してから名前の文字列を格納し、さらにそのメモリ領域へのポインタを配列に格納する。最後に、入力された人数分について、名前が格納さてているアドレスと名前の、文字列を出力するプログラムを作成せよ
<条件>
一人の名前の最大の長さは20バイト(全角文字で10文字分)とすること
アドレスの出力では、printf()における書式指定で%xを用い16進数で表記すること。
メモリ領域へのポインタを配列に格納してから文字列を格納しても構わない
↓自分が書いたソース
#include<stdio.h>
#include <stdlib.h>
int main(void){
char *name[5],*temp[5];
int i;
printf("名前を最大5人入力してください\n");
for(i=0; i<5 ;i++){
fgets(temp,20, stdin);
name[i+1] = (char *)malloc(20);
//name[i+1] = temp;
if(name[i+1] == "\0" )
continue;
printf("0x%x",*name[i+1]);
printf("%s",*name[i+1]);
}
free(name);
return 0;
}
↓エラー文
k2.c: In function ‘main’:
k2.c:10: 警告: passing argument 1 of ‘fgets’ makes pointer from integer without a cast
/usr/include/stdio.h:626: note: expected ‘char * __restrict__’ but argument is of type ‘char’
k2.c:12: 警告: assignment makes pointer from integer without a cast
k2.c:19: 警告: attempt to free a non-heap object ‘name’
最大5人の名前を格納するポインタ配列(例:char *name[5])を宣言する。
キーボードから一人ずつ名前を入力し、その名前の文字列を格納できる領域を確保してから名前の文字列を格納し、さらにそのメモリ領域へのポインタを配列に格納する。最後に、入力された人数分について、名前が格納さてているアドレスと名前の、文字列を出力するプログラムを作成せよ
<条件>
一人の名前の最大の長さは20バイト(全角文字で10文字分)とすること
アドレスの出力では、printf()における書式指定で%xを用い16進数で表記すること。
メモリ領域へのポインタを配列に格納してから文字列を格納しても構わない
↓自分が書いたソース
#include<stdio.h>
#include <stdlib.h>
int main(void){
char *name[5],*temp[5];
int i;
printf("名前を最大5人入力してください\n");
for(i=0; i<5 ;i++){
fgets(temp,20, stdin);
name[i+1] = (char *)malloc(20);
//name[i+1] = temp;
if(name[i+1] == "\0" )
continue;
printf("0x%x",*name[i+1]);
printf("%s",*name[i+1]);
}
free(name);
return 0;
}
↓エラー文
k2.c: In function ‘main’:
k2.c:10: 警告: passing argument 1 of ‘fgets’ makes pointer from integer without a cast
/usr/include/stdio.h:626: note: expected ‘char * __restrict__’ but argument is of type ‘char’
k2.c:12: 警告: assignment makes pointer from integer without a cast
k2.c:19: 警告: attempt to free a non-heap object ‘name’
Re:ポインタ
まず、fgetsの使い方は大丈夫でしょうか?
ここで宣言されたtemp
というのは
char* temp[5];
であってchar配列ではありません。
なのでエラーになります
fgetsのシンプルな使い方は
char Buffer[21];
fgets(Buffer,21,stdin);
ということになります
また、
name[i+1]とありますが、
最初i = 0なのでこれはひとつずれていませんか?
そして、
nameへのコピーも行われていないようです
他には、mallocがループで5回よばれるにもかかわらず、
freeが1つではメモリリークを起こします
必ず1対1に対応させましょう
このようにいくつかの問題がり、
コードを見る限り、かなり混乱されているのではないかと思います
なので、
入力を取るだけ、
メモリを確保してみるだけ、
アドレスを表示するだけ、
のように、エラーの出ている問題部分を分割して取り掛かってみてはいかがでしょうか?
また、念のためですが、
malloc(20);
charは1バイトなので、これで問題はないのですが、
malloc(sizeof(char)*20);
の方が汎用性のある書き方かなと思います、ご検討ください
ここで宣言されたtemp
というのは
char* temp[5];
であってchar配列ではありません。
なのでエラーになります
fgetsのシンプルな使い方は
char Buffer[21];
fgets(Buffer,21,stdin);
ということになります
また、
name[i+1]とありますが、
最初i = 0なのでこれはひとつずれていませんか?
そして、
nameへのコピーも行われていないようです
他には、mallocがループで5回よばれるにもかかわらず、
freeが1つではメモリリークを起こします
必ず1対1に対応させましょう
このようにいくつかの問題がり、
コードを見る限り、かなり混乱されているのではないかと思います
なので、
入力を取るだけ、
メモリを確保してみるだけ、
アドレスを表示するだけ、
のように、エラーの出ている問題部分を分割して取り掛かってみてはいかがでしょうか?
また、念のためですが、
malloc(20);
charは1バイトなので、これで問題はないのですが、
malloc(sizeof(char)*20);
の方が汎用性のある書き方かなと思います、ご検討ください
Re:ポインタ
そもそもtempはいらないですね。
>>fgets(temp,20, stdin);
>>name[i+1] = (char *)malloc(20);
>>//name[i+1] = temp;
>>if(name[i+1] == "\0" )
ここを変えて
name=(char *)malloc(22*sizeof(char));//文字列を格納できる領域を確保
fgets(name,22,stdin);//名前の文字列を格納
if(strcmp(name, "\n")==0)//文字列の比較はstrcmp関数を使います
こうですかね。
fgetsの仕様上、文字列の最後に"\n\0"が付加されるため、文字列の長さは22です。
そのため、空打ちすると、入る文字列は"\n"になります。
あと、free(name);では駄目です。
nameにメモリを確保したんですから、1つずつfree(name);と解放しなければいけません。
>>fgets(temp,20, stdin);
>>name[i+1] = (char *)malloc(20);
>>//name[i+1] = temp;
>>if(name[i+1] == "\0" )
ここを変えて
name=(char *)malloc(22*sizeof(char));//文字列を格納できる領域を確保
fgets(name,22,stdin);//名前の文字列を格納
if(strcmp(name, "\n")==0)//文字列の比較はstrcmp関数を使います
こうですかね。
fgetsの仕様上、文字列の最後に"\n\0"が付加されるため、文字列の長さは22です。
そのため、空打ちすると、入る文字列は"\n"になります。
あと、free(name);では駄目です。
nameにメモリを確保したんですから、1つずつfree(name);と解放しなければいけません。
Re:ポインタ
うしおさんと白い時空さんのおかげでコンパイルは通ることができました。しかし、実行してみると
��������5�����Ϥ��Ƥ�������
0x0(null)
セグメンテーション違反です (コアダンプ)
と表示されます。
まだ、おかしいみたいなのでどこを直した方がよいかアドバイスおねがいします
それから、(char *)malloc(22*sizeof(char))と(char *)malloc(20)の違いが調べてもよく分からないので教えてください
↓修正したソース
#include<stdio.h>
#include <stdlib.h>
int main(void){
char *name[5];
int i;
printf("名前を最大5人入力してください\n");
for(i=0; i<5 ;i++){
fgets(name,22, stdin); //変更
name = (char *)malloc(22*sizeof(char)); //変更
//name = ((char *)malloc(sizeof(char)*20);
//name = temp;
if(strcmp(name,"\n")==0) //変更
continue;
printf("0x%x",*name); //変更
printf("%s",*name); //変更
free(name); //変更
}
return 0;
}
��������5�����Ϥ��Ƥ�������
0x0(null)
セグメンテーション違反です (コアダンプ)
と表示されます。
まだ、おかしいみたいなのでどこを直した方がよいかアドバイスおねがいします
それから、(char *)malloc(22*sizeof(char))と(char *)malloc(20)の違いが調べてもよく分からないので教えてください
↓修正したソース
#include<stdio.h>
#include <stdlib.h>
int main(void){
char *name[5];
int i;
printf("名前を最大5人入力してください\n");
for(i=0; i<5 ;i++){
fgets(name,22, stdin); //変更
name = (char *)malloc(22*sizeof(char)); //変更
//name = ((char *)malloc(sizeof(char)*20);
//name = temp;
if(strcmp(name,"\n")==0) //変更
continue;
printf("0x%x",*name); //変更
printf("%s",*name); //変更
free(name); //変更
}
return 0;
}
Re:ポインタ
> fgets(name,22, stdin); //変更
> name = (char *)malloc(22*sizeof(char)); //変更
このように修正してください、という回答でしたか?
上下が逆ではなかったですか?
なお、fgets()の仕様は次のとおりです。
fgets()で、例えば
abc<Enter>
と入力したとき、結果を格納する配列には
a
b
c
'\n'
'\0'
が入ります。
改行'\n'と文字列終端'\0'の分を含めた領域を持っていなければなりません。
よって、有効データとして最大20バイトを確保したければ、
'\n'と'\0'を含めた22バイトの領域を定義しておかねばならない、
というのがくだんの回答の趣旨です。

> name = (char *)malloc(22*sizeof(char)); //変更
このように修正してください、という回答でしたか?
上下が逆ではなかったですか?
なお、fgets()の仕様は次のとおりです。
fgets()で、例えば
abc<Enter>
と入力したとき、結果を格納する配列には
a
b
c
'\n'
'\0'
が入ります。
改行'\n'と文字列終端'\0'の分を含めた領域を持っていなければなりません。
よって、有効データとして最大20バイトを確保したければ、
'\n'と'\0'を含めた22バイトの領域を定義しておかねばならない、
というのがくだんの回答の趣旨です。
