配列に関する疑問

このQ&Aのポイント
  • C言語で配列についての疑問があります。
  • 関数に文字列データを渡す際に、関数側でメモリの確保が可能かどうか知りたいです。
  • 具体的には、引数として受け取った文字列データを利用してメモリの確保ができるのかを知りたいです。
回答を見る
  • ベストアンサー

配列

こんばんは。 Cを勉強中の者なのですが 前に配列についての内容で自分も分からない事があったので投稿しました。 キーで文字列を入力して関数に渡し、 関数側で引数(文字列データ分)のメモリを確保する事は 出来るのでしょうか。 #include <stdio.h> #include <stdlib.h> void test(char *hiki); int main(void){ char inp[256]; scanf("%s",&inp); printf("%s\n",inp); test(inp); return 0; } void test(char *hiki){ char *i; i = (char*)malloc( ); /* 「hiki」をつかって出来るの でしょうか? */ 全然急ぎとかではなく、ちょっと疑問に思った事なのですが教えていただけるとうれしいです。 (考え方がおかしかったらスミマセン)

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

  • ベストアンサー
  • don_cha
  • ベストアンサー率34% (139/407)
回答No.1

以下のような形になりますね。 #include <stdio.h> #include <stdlib.h> #include <string.h> void test(char* hiki); void main(void) {   char inp[256];   scanf("%s", inp); /* ←&は要らない */   printf("%s\n", inp);   test(inp);   /* 適当な処理 */   /* return; ←省略可(関数の型はvoidなので、戻り値も要らない return 0ではコンパイルが通らない) */ } void test(char* hiki) {   char* i;   i = (char*)malloc(sizeof(char) * strlen(hiki));   /* i = (char*)malloc(strlen(hiki)); でも動きますが、 */   /* sizeof(char)を入れておいたほうが個人的には良いと思います */   /* 適当な処理 */   free(i); }

happy21
質問者

お礼

回答下さりありがとうございました。 細かなとこまで教えていただき、とても勉強になりました。 ありがとうございました。

その他の回答 (1)

  • Fooky
  • ベストアンサー率71% (59/82)
回答No.2

補足です。 void test(char* hiki) {   char* i;   i = (char*)malloc(sizeof(char) * (strlen(hiki)+1));   strcpy(i, hiki);   free(i); } のように、iに割り当てる配列の大きさは、strlen(hiki)よりも 最低でも1だけ大きくないといけません。お持ちのCのテキストの どこかに書いてあると思いますが、文字列には終端記号が最後につきます。 例えば、"ABC"という文字列は、配列内では   65 66 67 0 という形で4バイトの領域を使って保存されています。 また、strlen("ABC")は、4ではなく3を返す(終端文字は考慮しない) ので、strlen()を使ってmalloc()する時には注意が必要です。 あと、細かいことですが、文字列を読み込むだけなら、 scanf()よりもfgets()がお勧めです。scanf("%s", inp)は、 inpが何バイトの領域を持った配列かを考慮しないので、 256バイト以上読み込んでしまって、セグメントエラーに なる可能性があります。   fgets(inp, 256, stdin); とやることで、fgets()は256バイトよりも1バイトだけ 少ない(終端文字の分)文字をstdin(標準入力)から受け取って、 inpに格納し、最後に終端文字0をつけてくれます。

関連するQ&A

  • ポインタのポインタの初期化法

     文字列をポインタを使って扱うとき、例えば、初期化は次のように行えますよね。 #include <stdlib.h> char *s; s = (char *)malloc(1000); (これに続いてscanf("%s", s);など)  これと同様にして、二次元の配列を、ポインタのポインタを使って表したいとき、 char **s; と宣言したものを、malloc()関数を使って初期化することはできるのでしょうか。よろしくお願いします。

  • 動的に生成した文字列の配列を返す関数について

    動的に生成した文字列の配列を返す関数について お世話になります。 動的に文字列の配列を生成する関数を作ったのですが、 配列をうまく受け渡すことができず困っています。 以下のように入力された件数の数だけ "abc 0"~"abc n"という文字列を生成を行っています。 関数自体は期待通りの動作をしているようなのですが、 (Test1関数の最後でbfを確認しました) 呼び出し側にうまく配列を渡すことができません。 以下にソースを掲載いたしますのでどなたかご教示いただけたらと思います。 環境はVisualStudio2005です。 よろしくお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> void Test1(char **bf, int *cnt) { int i; int kensu; int charlength; char num[10]; char **nm1 = NULL; char **nm2 = NULL; printf("件数を入力:"); scanf("%d",&kensu); for(i=0; i < kensu; i++) { nm2 = (char**)realloc(nm1, sizeof(char*) * (i + 1)); nm1 = nm2; charlength=128; nm1[i] = (char*)malloc(sizeof(char) * (charlength)); strcpy(nm1[i], "abc "); itoa(i, num, 10); strcat(nm1[i], num); } bf = nm1; *cnt = i; return ; } void main() { int cnt; char **bf = NULL; Test1(bf, &cnt); printf("START\n"); printf("全部で%d件。\n", cnt); for(int i=0;i < cnt;i++) { printf("%s\n",bf[i]); } free(bf); printf("END\n"); }

  • 文字列中の空白部の読み込みの方法を教えてくださいm(_ _)m

    いつもお世話になっています!!キーボードから以下のような文字列を読み込み、大文字のみをカウントするプログラムを作りたいのですが、空白部になると次の文字を判定せずにプログラムが停止してしまいます。。。どなたかアドバイスをお願いしますm(_ _)m ○文字列 My name is Marly. ○プログラムソース #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void){ char *s; int i,j=0,m; s=(char*)malloc(sizeof(char)); printf("please iput sentens\n"); scanf("%s",s); m=strlen(s); for(i=0;i<m;i++){ if( 0x41 <= s[i] && s[i] <= 0x5A) j++; } printf("%d",j); free(s); return(0); }

  • VC++ 再帰関数

    ■キーボードより読み込んだ文字列の長さを求めるプログラムを再帰関数を使って作る #include <stdlib.h> int unk_r(char*p)   {    if(*p == 0x00)    return(0);   else    return(1+unk_r(p+1));   } int main()   {    char *i;    i = (char *)malloc(20);    scanf("%s",i);    printf("%d\n",unk_r(i));   } このプログラムについて、行、単語ひとつひとつ細かいところまで具体的に解説お願いします。どういう働きをしているのか等。 例えば #include <stdlib.h> はmallocを使うのに必要などなど。 よろしくお願いします。

  • 参照渡しにならないのは何故?

    参照渡しにならないのは何故? 基本的な質問で大変恐縮なのですが、C言語で以下のコードを書いてみました。 メインの関数ではchar型のポインタのみ用意し、呼び出し先のtest関数内で当該ポインタ用に 領域を割り当て文字列をコピーしています。 ここまでは良いのですが、呼び出し元のメイン関数に戻るとtest関数にて設定したはずの値 が消えてしまいます。 結局のところ、メインの関数で用意したchar型のポインタがうまくtest関数にわたっていない (?)ような動作なのですが、どうしてこうなってしまうのか理解できず苦しんでいます。 ご教授いただければ幸いです。 #include <stdio.h> #include <stdlib.h> #include <string.h> void test(char *pc_buf){ pc_buf = (char *)malloc(10); memset(pc_buf,(int)NULL,10); strcpy(pc_buf,"12345"); return; } void main(){ char *pc_buf; pc_buf = NULL; test(pc_buf); printf("[%s]\n",pc_buf);getchar(); }

  • C言語 動的なメモリの確保 実行できない

    malloc関数を使いメモリを確保しそこへ"ABCD"と記憶させ、ポインタ*Cを使い確保したメモリの内容を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int i;   char *C;   C = (char *) malloc (sizeof(char) * 5);   C = "ABCD";   for(i = 0; i < 5; i++){     if(C[i] != NULL){       printf("%s", C[i]);    ←※エラー※     }   }   free(C);   return 0; } ********************************************* 正常にコンパイルできますが実行エラーになります。VCを使いF10のデバッグテストで※のところエラーになります。なぜなのでしょうか?

  • 文字列の探索

    ファイル名を指定して文字列の探索を行うというプログラムを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); }

  • 末尾にコピーするプログラム

    大学で 「main関数でキーボードからの2つの文字数を受け取り、関数を実装し仮引数に文字列s1、文字列s2をとり、s2をs1末尾にコピー(s1とs2を連結)するプログラミングを作成しなさい」 void cat(char *s1,char *s2) という問題がありました。以下、その回答を考えたのですがこれで大丈夫ですか? #include <stdio.h> void cat(char *s1, char *s2); void main(void); void cat(char *s1, char *s2) { while ((*s1++ = *s2++) != '\0') ; } void main(void) { char s1[100]; char s2[100]; printf("一つ目の文字列を入力してください。:",s1); scanf("%s",s1); printf("二つ目の文字列を入力してください。:",s2); scanf("%s",s2); cat(s1, s2); printf("コピー後: = %s\n", s2); }

  • 文字列のコピー

    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);で処理が止まってしまいます。入力した文字列を表示できるように、御指摘お願いします。

  • 3次元配列でのポインタ

    唐突ですみません。 サイズが640*480の画像を180枚読み込むプログラムをポインタを使って作成しようと考えています。 以下で示すプログラムは画像を読み込むための作成したものですが、エラーが出てしまい実行することができません。 間違えている箇所があればご指摘お願いします。 また、そのほかに効率の良いやり方などがありましたらご教授願います。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define xsize 640 #define ysize 480 #define round 180 #include "Input.h" void Input_task(unsigned char ***In); void main() {   static unsigned char ***In;   int i,j;   In=(unsigned char***)malloc(sizeof(unsigned char)*round);   for(i=0;i<round;i++)   {     In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);     for(j=0;j<ysize;j++)     {       In[i][j]=(unsigned char*)malloc(sizeof(unsigned char)*xsize);     }   }   Input_task(In); } Input.hの中身 void Input_task(unsigned char ***In) {   char filename[30];   int i,j,k;   FILE *fp;   for(i=0;i<round;i++)   {     sprintf(filename,"b20_%04d.raw",i);     fp=fopen(filename,"rb");    for(j=0;j<ysize;j++)     {       for(k=0;k<xsize;k++)       {         *(*(*(In+i)+j)+k)=(unsigned char)getc(fp);       }     }    fclose(fp);   } }

専門家に質問してみよう