• ベストアンサー

プロンプト入力 malloc( )

#include <iostream.h> void f(char* str); main(){ char s[8] = "\0"; cout << "文字を入力" << '\n'; fgets(s, 8, stdin); f(s); } void f(char* str){ char* c; c = (char*)malloc(sizeof(char) * strlen(str)+1); cout << strlen(str) << '\n'; cout << sizeof(c); free(c); } - 結果 - 文字を入力 ( a、Ctrl+Z ) a 1 4 でした。 cout << sizeof(c); の結果は4でした。1バイトの入力だから\0を含めて 2バイトを確保したかった。 そのためにはどうしたらいいんですか? どうして4だったんですか? 文字を入力するとこで、Ctrl+Z の代わりに Enter を押すと Enter まで s に格納されてしまう。 cin を使うと8バイト以上の入力でも s に格納されてしまう。 そうならないためのよい方法があったら教えてください。

  • A__
  • お礼率59% (194/328)

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

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

>1バイトの入力だから\0を含めて2バイトを確保したかった。 >そのためにはどうしたらいいんですか? 安心してください。この方法で2バイト分のメモリ領域が確保できています。 >どうして4だったんですか? cはcharポインタ型変数だからです。 ポインタ型のサイズは元の変数の型によらず一定値となります。 半分しか答えていないので自信は「なし」とさせていただきます。

A__
質問者

お礼

ありがとうございます。 4はポインタのサイズだったんですね。 cout << sizeof(*c); で分かりました。

その他の回答 (1)

noname#4147
noname#4147
回答No.2

>1バイトの入力だから\0を含めて 2バイトを確保したかった。 >そのためにはどうしたらいいんですか? >どうして4だったんですか? 2バイト確保されているはずですよ。 実際に、sizeof(char) * strlen(str)+1 の値を出力されると、 2バイトになっていませんか? ポインタcには、確保したメモリ領域の先頭アドレス番地が格納されているので sizeof(c)では、確保したメモリの大きさではなく、 ポインタc自体のバイト数が表示されているのです。 実際にcの値を表示してみると分かると思います。 >文字を入力するとこで、Ctrl+Z の代わりに Enter を押すと >Enter まで s に格納されてしまう。 >そうならないためのよい方法があったら教えてください。 fgetsを使うと、復改文字が残るのは当然です。 gets(s)等を使うと手軽だと思います。 ただ、s[8]を超えない処理が必要です。

A__
質問者

お礼

sizeof(char) * strlen(str)+1 の値を出力されると2バイトになりました。 入力決定時の Enter については未解決だけど 1番知りたかった4の疑問が解決してよかったです。 ありがとうございました。

関連するQ&A

  • ポインタ勉強中です。しかも実行するとおかしいです。

    <本に載ってたソース> #include<stdio.h> #include<string.h> int main() { char msg[20]; char *str=NULL; int i; int cnt; str=&msg[0]; printf("文字を入力してください"); scanf("%s",&str); cnt=strlen(msg); str=msg+cnt; for(i=cnt;i>=0;i--){ printf("%c",*(str--)); } printf("\n"); return 0; } char *str=NULL;は、ポインタstrを空にするということでしょうか? いつもながらstrlenとsizeofが混じります。 sizeofがバイトの大きさで、strlenが、文字数でしたっけ?

  • mallocがうまく動かない

    コマンドライン引数で指定された文字列を逆順に返すプログラムを作るため 下記のようなプログラムを組みました。 ところが変数strの大きさがargv[1]より大きくなってしまいます。 どうすればよいのでしょうか。 #include <stdio.h> #include <stdlib.h> char *mstrrev (char *s); int main(int argc, char *argv[]){ char *str; str = mstrrev(*(argv+1)); printf("%s",str); free(str); } char *mstrrev (char *s){ int length,i; char *str; for(length=0;*(s+length)!='\0';length++); str = (char *)malloc(sizeof(char)*length); for(i=0;i<length;i++){ str[i] = s[length-1-i]; } return str; }

  • const 回りのエラー?

    以下のプログラムをcygiwn 上でコンパイルすると エラーが出るのですが 何がいけないのかよくわかりません。 メッセージを読んでconst 回りなのかな?とは思っているのですが… よろしくお願いします。 #include<iostream> #include<cstring> #include<cstdlib> using namespace std; class sample{ char *s; public: sample(); sample(const sample &ob); ~sample(){if(s) delete [] s; cout << "Freeing s\n";} void show(){cout << s << "\n";} void set(char *str); sample operator=(sample &ob); }; sample::sample() { s = new char('\0'); if(!s){ cout << "Allocation error\n"; exit(1); } } sample::sample(const sample &ob) { s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,ob.s); } void sample::set(char *str) { s = new char[strlen(str)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,str); } sample sample::operator=(sample &ob) { if(strlen(ob.s)>strlen(s)){ delete [] s; s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } } strcpy(s,ob.s); return *this; } sample input() { char instr[80]; sample str; cout << "Enter a string: "; cin >> instr; str.set(instr); return str; } int main() { sample ob; ob = input(); ob.show(); return 0; } <コンパイル結果> In function 'int main()': 78:error:no match for 'operator=' in 'ob = input()()' 49:note:candidates are: sample sample::operator=(sample&)

  • malloc関数について質問です。

    整数を入力してその分だけ動的にメモリを確保し、その後文字列を入力して確保した領域に格納し、表示するプログラムなんですが、 int main(void) { int n; char *p; puts("整数を入力"); scanf("%d", &n); p = malloc(sizeof(char) *(n+1)); puts("文字を入力");   scanf("%s", p); printf("文字列は%s\n", p); free(p); return 0; } としたら、ちゃんとプログラムは動くんですが、 問題の意図にあっているんでしょうか?

  • malloc関数について。

    typedef struct a{ char *simei; int nenrei; }MEIBO; void main(void) { MEIBO a[5]; int wa; for(i = 0; i <= 4; i++ ) { a[i].simei = malloc(100 * sizeof(char) ); if( a[i].simei == NULL ) /* 領域確保に失敗したか */ { printf( "%dバイトの領域確保に失敗", 100 * sizeof(char) ); return 1; } printf("%d番目を入力してください\n",i+1); scanf("%s",&a[i].simei); printf("%s\n",a[i].simei); } C言語初心者です。これで入力したa[i].simeiが表示されないのですが、間違いを指摘していただけますでしょうか。宜しくお願いします。

  • プログラム

    文字列を逆順にする関数を作ってるのですがうまくできません。 void reverse(char *str, int count=0) { int i; char *s="momonga"; s+=strlen(s); count=strlen(s); for(i=count; i<0; i--, str++, s--){ *str++=*s++; } } int main() { char s1[20]; int c; reverse(s1,c); printf("%momongaを逆順にすると%sで文字数が%dです",s1,c); return 0; } このプログラムの間違ってる所をおしえてください。

  • 検索するプログラミング

    C言語の問題で、ユーザが文字列を入力し、半角英数字の入力(最大でも1000文字)を改行があるまで受け付ける。次に、ユーザに検索する文字列(最大でも半角20文字)を入力させ、はじめに入力された文字列内にあるかどうかを表示するプログラムを作成する。配列の外部を参照しないように注意する。そのプログラム内で以下の関数を完成させる。 int str_srch (char str [], char srch_str[]) : 文字列strの中に文字列srch_strが含まれていれば、1を返し、含まれていなければ0を返す関数とする。 このような感じになると思うのですがどなたか分かりませんか? int str_compare(char *s1, char *s2) { //文字列s1の先頭にs2が含まれていれば等しいければ1、 //そうでなければ0を返す //while文を利用して、s2の1文字目からs2がヌル文字になるまで //繰り返し、s1の対応する文字と等しいかどうかチェック //s2の最後の文字まで等しければ、1 //そうでなければ0を返す } int str_length(char *str) { //文字列strの長さを返す } int str_srch(char *str, char *srch_str) { int strlen, srch_strlen; int i,j=0; strlen =str_length(str); //文字列strの長さ srch_strlen =str_length(srch_str); //文字列srch_strの長さ for(i=0;i<strlen;i++){ //strのi文字目からにsrch_strがあるかどうか  j=j+str_compare(&str[i], srch_str) } //jは文字列srch_strが文字列strに何回含まれているか、を表す //jが1より多くなれば1を返し //jが0なら0を返す }

  • C++

    今、下のようなプログラムを作っています #include <iostream> #include <iostream> using namespace std; int i=0, c=0, n; char str[10]; class X16karax10{ //16進から10進ヘ public: void keisan(); }; void X16karax10::keisan(void){ cout<<"16進を入力して下さい"<<endl; cout<<"英数字は大文字で入力してください(F→○ f→×)" <<endl; scanf("%s",str); while(str[i] != '\0'){ n = n * 0x10; c = str[i++]; if((c >= '0') && (c <= '9')){ n += c - '0'; } else if((c >= 'A') && (c <= 'F')){ n += c - 'A' + 10; } } cout<<("%d\n",n)<<"です\n"<<endl; } int main(){ for(i=0; ; i++){ X16karax10 p; p.keisan(); } } 16進を十進に変えるものなのですがreturn 0を使うと「X16karax10::keisan()' は値を返せない」と、でてしまうのですがどうしたらよいでしょうか?

  • sprintf

    文字列に1文字を結合したいんだけど、 例えば  char str[] = "xy";  char c = 'z'; があって、2つを結合する場合、 #include <iostream.h> main(){  char str[] = "xy";  char c = 'z';  char buf[2];  buf[0] = c;  buf[1] = 0;  strcat(str, buf);  cout << str; } でもいいけど、もっと簡単にする方法があったら教えてください。  char str[] = "xy";  char c = 'z';  sprintf(str, "%s%c\0", str, c);  cout << str; イメージ的にこうだけど、失敗しました。

  • 文字の並べ替え

    C言語で文字の並べ替えをしたいのですが条件があり ポインタを使って文字を並べ替える別の関数をを渡さなければなりません.(void reverse(char *str)をつくる) そこで作ったのが #include <stdio.h> #include <string.h> void reverse(char *str); int main(void){ char s[80]; gets(s); reverse(s); printf("%s\n",s); return 0; } void reverse(char *str){ char q[80]; int i,n; n=strlen(str)-1; str+=n; for(i=0;i<=n;i++)q[i]=*str--; str++; q[i]='\0'; for(i=0;i<=n;i++)*str++=q[i]; } なのですが ポインタを使っている意味が余りないので ポインタを使うよりよいプログラムを教えてください. (アドバイスでもかまいません.)