• ベストアンサー

ポインタの基本的な問題

ポインタの勉強をしています。変数にポインタが付いている場合の動作は大体理解したつもりですが以下のように関数にポインタが付いているとどう扱えばいいのかわかりません。とりあえず、まずはtsukinonamae関数にinteger 1を渡して「1月」と表示させることから始めようとしていますが、それすらコンパイルエラーになります。引数nに1を渡すところはいいですよね?その後、nam[1]に入っているjanという文字列をchar型で返す?と思うのでメイン部で宣言したcharに渡そうとしているのですが。。 何が問題なのでしょうか。 char *tsukinonamae(int n); int main(){ int n = 1; char s[30]; s = tsukinonamae(n); printf("%s\n", s); } char *tsukinonamae(int n){ static char *nam[] = { "none", "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; return (n<1 || n>12) ? nam[0] : nam[n]; }

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

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

下のようにすると、エラーは出ません(BorlandC++5.6.4) #include <stdio.h> char *tsukinonamae( int n ) {  static char nam[13][8] = {   "none",  // 単独行   "jan", "feb", "mar", "apr", "may", "jun",   "jul", "aug", "sep", "oct", "nov", "dec"  };  return( ( n < 1 || n > 12 ) ? nam[ 0 ] : nam[ n ] ); } void main() {  int n = 1;  char *s;  s = tsukinonamae( n );  printf( "%s\n", s );  printf( "%c%c月\n", 0x82, ( 0x4F + n ) ); // 「1月」と表示させる } 注:インデントに全角空白を用いています。タブに一括変換して下さい。

redhat_001
質問者

お礼

ご回答有り難うございました。

その他の回答 (3)

回答No.4

 まず,コンパイラのエラーメッセージをよく読みましょう。5行目で代入不可能と言ってますよ(gccの場合)。   s = tsukinonamae(n); の左辺の s は配列名ですから定数であり,代入できません。文字列をコピーしたいのなら,他の皆さんがおっしゃるとおり strcpy 関数や strncpy 関数を使います。また, #include <stdio.h> /* printf用 */ #include <string.h> /* strcpy, strncpy用 */ を書く習慣をつけておいたほうがいいでしょう(上記のコメントを付ける必要はありません)。  ポインタの学習と同時に配列の復習もしてください。似ている点と違っている点。  がんばってください。

redhat_001
質問者

お礼

ご回答有り難うございました。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

>それすらコンパイルエラーになります。 コンパイルエラーがなにを言っているのかをまずよく読みましょう。 >nam[1]に入っているjanという文字列をchar型で返す?と思う いいえ、tsukinonamae() は文字列 "jan" の先頭アドレス(char* 型)を戻しています。 それを印字したいだけなら printf("%s\n", tsukinonamae(1)) とするか、 char s[30] に strncpy() などで内容をコピーしてから印字しましょう。

redhat_001
質問者

お礼

ご回答有り難うございました。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

char s[30]; を char* s; にすればエラーはでなくなると思います もしくは s = tsukinonamae(n); を strcpy(s, tsukinonamae(n)); に変更 ポインタと配列は似てるところもありますが違うものです

redhat_001
質問者

お礼

ご回答有り難うございました。

関連するQ&A

  • 月名でソートを行いたいのですが・・・

    Solaris8上で、ソートコマンド『sort -M 入力ファイル名』をやったのですが、上手く月名でソートを行ってくれません。入力ファイルは、月名のみのレコードが書かれたテキストファイルです。以下に、私が入力した月名を示します。 JAN、FEB、MAR、APR、MAY、JUN、 JUL、AUG、SEP、OCT、NOV、DEC もう一点、同一レコードを削除する『-u』オプションも上手く動きません。 どなたかご存知でしたら教えて頂けませんか? 宜しくお願い致します。

  • エクセルについて

    エクセルについて 会社のエクセルで、例えば、34-07と入力すると、Jul-34と変換されます。 でも、56-78と入力するとなにもなりません。 どうやら、01,02,03,04…11,12だと、それぞれ、Jan,Feb,Mar,Apr…Nov,Decと英語での月の名前に変換されてしまいます。 セルの書式設定で直しても、直りませんでした。なぜか、ユーザー定義という設定になってしまいます。 どうしたら、56-04と入力しても、Apr-56という風にならず、56-04と入力できるようになりますか?

  • 一月前の日付を求めるプログラム(pascal)

    大学の課題で「一月前の日付を求めるプログラムを作れ。その日が無ければその月の最後の日を示す。」というのが出題されました。12月18日(火)と入力すると11月18日(日)、12月31日(月)なら11月30日(金)となる具合です。 列挙型を用い書いてみたのですが、コンパイルしたら「Type-clash」と出てコンパイルできませんでした。どう改善すべきかアドバイスお願いします。 program calender(input,output); type months=(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Nov,Oct,Dec); weeks=(Mon,Tue,Wed,Thu,Fri,Sat,Sun); var x,x1,z,z1:char; y,y1,p1,p2,i,r:integer; begin writeln('月:'); readln(x); writeln('日:'); readln(y); writeln('曜日:'); readln(z); if x=Jan then begin x1:=Dec end else begin x1:=pred(x)            {x1=表示する月} end; if y>=29 then if x=Mar then begin y1:=28 end else begin y1:=y             {y1=表示する日} end; case x of May,Jul,Aug,Nov,Dec : p1:=30; Jan,Feb,Apr,Jun,Sep,Oct : p1:=31; Mar : p1:=28 {月の違いによる日数の違い} end; p2:=y-y1;     {日にちの違い} r:=(p1+p2)-trunc((p1+p2)/7)*7; {7で割った余り} for i := 1 to r do z1:=pred(z);          {z1=表示する曜日} writeln(x1,'月',y1,'日',z1,'曜日') end.

  • ポインタと文字列(C言語)

    サンプルソース char *myfgets(char *s, int n, FILE *in){-----(1) int ch; while((ch = fgetc(in)) != '\n'){ if(ch == EOF) return NULL; *s++ = ch; if(*s == (n - 1))------(2) return NULL; } *s++ = '\n'; *s = '\0'; return s; } 自分でfgets関数を作ろうという課題なのですがポインタがいまいちつかめません。 (1)のchar *myfgetsの部分の関数のポインタというのは要するにどういうことに使うのでしょうか? (2)の場合の*sは配列の要素数を表しているのでしょうか?

  • 非常に基本的なポインタの使い方

    非常に基本的なところだと思いますが、ポインタの理解がうまくなく意図どおりのプログラムが書けません。 何らか引数を渡して(とりあえず文字列"hogehoge"を渡す)、そのポインタaをtest関数に渡して、ちゃんと"hogehoge"が渡っていれば「pass」と出力する 意図なんですが、どうもうまくいっていないようです。 ----------------------------- int test(char* a) { if(a == "hogehoge"){ printf("pass\n"); }else{ printf("ng\n"); } return 0; } int main(int argc, char* argv[]) { char* a = argv[0]; // "hogehoge"を渡しているとします。 test(a); return 0; } ----------------------------- 何がおかしいのか理解ができず、困っています。 ちなみに char* a = argv[0]; の箇所を単純に char* a = "hogehoge"; とした場合はうまくいくので、余計に混乱しております。 どなたか、正解例をご教授いただけませんでしょうか。

  • 掲示板のcookieが消える?

    自分のサイトに設置してあるBBSなんですが、cookieで名前やメアドを記憶しているはずが、ある日を境に出なくなったんです。 cookieは60日間有効にするために、以下のように書いています。 local($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime(time+60*24*60*60); @month=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", $week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec); $cook="name<>$in{'name'}\,email<>$in{'email'}\,url<>$in{'url'}\,pwd<>$in{'pwd'}\,icon<>$in{'icon'}\,color<>$in{'color'}"; そして、これをprintで書き出しているのですが、なぜ消えてしまうんでしょう? 設定の仕方が間違っています?

  • ポインタ

    String String Mid(int start, int length) const { char *p="HelloWorld"; char s[100]; p+=start; for(int i=0;i<length;i++) { *s++=*p+;; } return s3; で++には左辺値が必要ですとでます。 stringクラスのMid関数を実装しているのですが start分ポインタを進めてlength取り出す関数なんですが ここまでは組んだのですが、うまくいきません。 どうすればうまくいきますか?

  • 問題のあるポインタ変換

    char *x; int i; x = f( i ); で、fは char * ( int y ); と言った関数なのですが、 警告で、問題のあるポインタ変換と出てしまいます。 これはなぜでしょう?ご教授お願い致します。

  • ポインタ

    字列2つを入力し,同じ文字列かどうかを判定するプログラム ポインタの操作で文字列の比較を実現する。 (ライブラリ関数 strcmp を仕様しない) 関数の中身が上手に実現出来ません。 文字列を指すポインタ変数 2 つを引数に取り,同じ文字列なら -1 を,異なる場合は先頭から一致した文字数 を返す関数 必ず,具体的な解答を提示して下さい。 char str__com(char *s,char *t,int count) { while(*s = *t != '\0'){ if(s != t){ return -1; } if(s == t){ count++; } {s++;t++;} } return -1; }

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

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