• 締切済み

ポインタの文字列

例えば char buf[] = "てすと"; printf("%s", buf[2]); は問題ないですが、 char *buf = "テスト"; printf("%s", buf[2]); は間違った使い方ですか?

みんなの回答

  • jagd-doga
  • ベストアンサー率31% (14/45)
回答No.6

No.4です。 下記の件について補足します。 > ポインタについて添え字演算子[]を使うことはまったく問題ありません。 > (これはNo.3、No.4の方の勘違いでしょう) 確かにNo.5の方のおっしゃるとおり、「ポインタの添え字」はありです。 No.5さんの書き方でもそのとおりに動くのかもしれません。 (すみません。ためししてません) ただ質問者の方は、ポインタを配列で宣言していません。 配列で宣言していない変数に添え字を使うのは基本的にナシかと・・・ ●個人の書き方の問題かもしれませんが・・・

全文を見る
すると、全ての回答が全文表示されます。
  • kmb01
  • ベストアンサー率45% (63/138)
回答No.5

(1)char buf[] = "てすと"; (2)char *buf = "テスト"; No.4の方が言っているようにメモリ上の配置がまったく異なりますが、 bufの指す領域に書き込みを行わない限りほとんど同じ様に利用できます。 ポインタについて添え字演算子[]を使うことはまったく問題ありません。 (これはNo.3、No.4の方の勘違いでしょう) printfは何がしたいのかによってどちらが間違いかが決まります。 "スト"と表示したいのなら printf("%s",buf+2);もしくは printf("%s",&buf[2]);ですし、 "ス"と表示したいのなら printf("%c%c", buf[2],buf[3]); となります。

全文を見る
すると、全ての回答が全文表示されます。
  • jagd-doga
  • ベストアンサー率31% (14/45)
回答No.4

(1)char buf[] = "てすと"; (2)char *buf = "テスト"; 上記の二つの宣言ですが、プログラム的に意味がまったく違います。 (1)はメモリ上にbufというchar型の配列が少なくとも7バイト(注)確保され、その領域に"てすと"と言う値が書き込まれます。 (注)2バイト文字3つの後ろに1バイトのNULL文字が付くので、最低7バイトになります。 (2)は、まずメモリ上に静的に"テスト"という文字列と、bufというchar型の4バイト(注)のポインタが確保され、bufというポインタに"テスト"の先頭アドレスが代入されます。 (注)4バイトとなるのは32ビットマシンの場合。64ビットマシンだと8バイトになります。 ということを踏まえると、 > char buf[] = "てすと"; > printf("%s", buf[2]); bufは配列でとっているので正解です。 (ただし &buf[2] ならば、ですけど。) > char *buf = "テスト"; > printf("%s", buf[2]); bufは配列ではないので、この書き方は誤りだと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • ryuta_mo
  • ベストアンサー率30% (109/354)
回答No.3

buf[]は配列 *bufはポインタです。 ポインタを配列のようには扱えなかったとおもいます。 もしコンパイルが通ってもほかのコンパイラで通らない可能性があるのでそういうのは避けるべきです。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

えー、宣言の仕方によって、buf[2]という表現が有効だったり無効だったりするか? という意味ですか? ポインタと、配列名は互換があったような気がするのですが、厳密には規格を参照する必要があるでしょう。 でも、実際この二つで扱いの違う(片方Errorを出す)コンパイラはないと思いますが・・・ もちろん、#1の方の指摘通り、”%s”で、char型はダメですが・・・

全文を見る
すると、全ての回答が全文表示されます。
  • gimmick
  • ベストアンサー率49% (134/270)
回答No.1

どちらも問題ありだと思います。 「すと」や「スト」を表示したいのであれば、 printf("%s", &buf[2]); または printf("%s", buf + 2); としてください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 文字列リテラルの途中の文字を指すポインタについて

    文字列リテラルの途中の文字を指すポインタについて 下記のプログラムで途中の文字を指すポインタは、&s1[7]で 書かれていますが, s1+7と書けないでしょうか、問題点を教えてください。; int main(void) { char *s1 = "Bohyo takahoshi"; char *s2 = &s1[7]; printf("フルネームは%sです\n",s1); printf(フアミリールームは%sです\n",s2);

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

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

  • 文字列の比較に関する質問

    文字列をif文で比較したいのですが、まず下記の例だと char *a a="a"; if(a=="a"){ printf("等しい"); }else{ printf("等しくない"); } 文字列は等しくなるのですが下記の例ではなりません 何故なのでしょうか。 read(s_sock,&buf,sizeof(buf)) if(a=="GET"){ printf("TRUE") }else{ printf("FALSE"); }

  • C++ ハードウェアから文字列受信 文字化け

    C++初心者のため大変困っております。 正直に申し上げますと、だれか助けて下さい。 どなたかご教授宜しくお願いいたします。 まずは簡単な仕様から JavaでC++を呼び出し、C++でハードウェアを動かします ハードウェアから文字列を受け取り、Javaに返すというプログラムを開発しております。 以下に現在の状況を示します ・C++のプロジェクト→プロパティ→マルチバイト文字を使用する にチェックを入れました ・ソースです↓ 以下をJavaから呼び出し、戻り値を取得しています printfがたくさんありますが、文字列をチェックするためのものです。ご了承ください。 JNIEXPORT jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj) { BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3");     //ハードウェアにコマンドを送信する関数です     //レスポンスが、s3のアドレスに格納されます。      crwSendCommandRR(           4,        //ポート番号           1,        //ポーリングフラグ           10000,     //タイマー           0,        //タイマー           1,        //DSR信号線チェックフラグ           "DT",     //コマンドコード           ":1",      //ハードウェアに送信するパラメータ           2,        //パラメータの長さ           &s1,      //レスポンスを格納するアドレス 1            &s2,      //レスポンスを格納するアドレス 2           &s3      //レスポンスを格納するアドレス 3    ); printf("s3:\n", s3); printf("s3:%d\n", s3); printf("s3:%x\n", s3); printf("s3:%s\n", s3); //BSTR を char に変換---------------------------------------------- char buf[64]=""; WideCharToMultiByte( CP_ACP,           // コードページ ANSI コードページ WC_NO_BEST_FIT_CHARS,// 処理速度とマッピング方法を決定するフラグ (OLECHAR*)s3,      // ワイド文字列のアドレス -1,             // ワイド文字列の文字数 buf,            // 新しい文字列を受け取るバッファのアドレス sizeof(buf) - 1,    // 新しい文字列を受け取るバッファのサイズ NULL,          // マップできない文字の既定値のアドレス NULL           // 既定の文字を使ったときにセットするフラグのアドレス ); int len = strlen(buf); for(int i = 0; i < len; i++) { printf("\nbuf:", buf[i]); printf("\nbuf:%d", buf[i]); printf("\nbuf:%x", buf[i]); } char* src = buf; printf("\nsrc:",src); printf("\nsrc:%d",src); printf("\nsrc:%x",src); printf("\nsrc:%s",src); jstring jstr = env->NewStringUTF(src); printf("\njstr:", jstr); printf("\njstr:%d", jstr); printf("\njstr:%x", jstr); printf("\njstr:%s", jstr); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); return jstr; } ・実行結果 Java側 ?????   //?になります。本来なら 1:19900309 C++側  s3: s3:3150196 s3:301174 s3:1:19900309 c: c:3150196 c:301174 c:1:19900309 buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f src: src:71756992 src:446ecc0 src:???? jstr: jstr:65927816 jstr:3edfa88 jstr:Pァ$@ヌ#@ヌ#@ヌ#(CO どうもWideCharToMultiByteの使い方が悪いのかと思うんですが C++初心者のため、どこがどうおかしいのか答えが出せずにおります 他に何かございましたら補足致しますので宜しくお願い致します。

  • 指定した文字列を探して・・・

        第1引数の文字列中に第2引数で指定した文字がある場合に、その     文字のあるアドレス(ポインタ)を返す関数doko()作成し、     プログラムを完成させよ。     指定した文字がない場合はNULL(ヌルポインタ)を返すものとする。     配列の[](カギカッコ)を利用しないで作る事     main内は変えないこと いろいろと模索したのですが、strcpyなどは使うのでしょうか? 参考サイトを見たりしたり、ほかの質問などを見たのですが なかなか理解できずに現在にいたってます 以下のコードのdokoは沢山やりすぎたので一番シンプルな間違い方をしています 何かご指摘あればお願いします #include <stdio.h> #define MAX 128 char* doko(char *,char); int main() { char buf[MAX]; char *p = "abcdef12345"; char *r; r = doko(p, 'f'); if (r == NULL) { printf("mojiretsu ni f toiu moji ha arimasen\n"); return 0; } printf("%s (= f12345)\n", r); scanf("%s", buf); r = doko(buf, 'x'); if (r == NULL) { printf("mojiretsu ni x toiu moji ha arimasen\n"); return 0; } printf("%s\n", r); return 0; } char* doko(char *p,char a) { while(*p){ if(*p == a){ return p; } if(*p != a){ return NULL; } ++p; } }

  • C言語で文字列をポインタ名にしたい

    C言語で文字列をポインタ名にしたい 題名のとおりですが、C言語で文字列をポインタ名にする方法はありますか? 具体的にはxの配列の個々の要素を、計算回数による計算結果の推移をファイルに出力したいと考えています。 ファイル名は「test_x_1.data」、「test_x_2.data」、…「test_x_50.data」のようになっています。 (要素分のファイルを作成するということです。) ここでそれぞれの「test_x_1.data」、「test_x_2.data」、…「test_x_50.data」には、 x[i]の計算回数と計算結果が格納されていますが、 現状では、fopenとfcloseを計算回数分繰り返しているため、計算時間がかかってしまっています。 よって、計算を行う前の最初にfopen、最後にfcloseを行うようにしたいのですが、 ファイルポインタを開く作業を手動で行うと、xの要素分ファイルポインタを用意しなくてはならなくなります。 (現状のようにファイルポインタを使いまわすのではなく、 要素分(=ファイル数)のファイルポインタを、常に開きっぱなしにしたいということです。) そのため、文字列をポインタ名にすることで、その作業を自動で行えるようにできればと考えています。 実際にchar型の配列が文字列になっているため、「FILE *buf」のように宣言しようと試みたのですが、 bufは既に文字列型の配列として宣言されているため、使用することができませんでした。 (文字列そのものをファイルポインタ名にできなくても、 この場合、要素数分のファイルポインタを自動で用意できれば問題ないのですが…) 下は簡単なプログラム例です。詳しい方のご助言を戴ければ幸いです。 よろしくお願い致します。 -------------------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <math.h> #define CAL 10000 /*計算回数*/ #define ELE 50 /*配列の要素数*/ #define NUM_CHAR 20 /*char型で確保する文字数*/ int i,j,n; /*forループ用*/ double x[ELE]; /*計算結果の配列*/ char buf[ELE][NUM_CHAR]; /*文字列*/ int main(void){ char filename[] = "test_x_"; char fileext[] = ".data"; /*「test_x_数字.data」という文字列の出力*/ for(i=0;i<ELE;i++){ sprintf(buf[i],"%s-I%d%s",filename,i,fileext); } for(n=1;n<CAL;n++){ /*計算部分*/ for(i=0;i<ELE;i++){ x[i] = 2*n+i; } /*ファイルに出力*/ for(i=0;i<ELE;i++){ FILE *fp; /*このファイルポインタ名を要素数分用意したい*/ if(n==1){ if((fp = fopen(buf[i],"w"))==NULL){ printf("The program can't create a file. : buf[i] \n"); exit(1); } } if(n>=2){ if((fp = fopen(buf[i],"a+"))==NULL){ printf("The program can't read a file. : buf[i] \n"); exit(1); } } fprintf(fp,"%d %f\n",i,x[i]) fclose(fp); } } return 0; } --------------------------------------------------------------------------------

  • C の文字列置き換え

    #include <stdio.h> // buffer overflowは無視している文字列置き換え関数 void replace(char *buf, char *pre, char *aft) {   char *p;   p = strstr(buf, pre);   if (p){     char *p_2 = p + strlen(pre);     replace(p_2, pre, aft);     memmove(p + strlen(aft), p_2, strlen(p_2)+1);     memcpy(p, aft, strlen(aft));   } } int main(void) {   char buf[1024] = "C:\\programfile\\LOG";   replace(buf, "LOG", "RESULT");   printf("%s\n", buf);   return 0; } というソースが以前出ていたのですがこのバッファーオーバフローはどうすれば回避できるのですか? お願いします

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

    C言語を独学で始めたばかりの者です。 ポインタのところまでいきましたが、以下のプログラムを配列で書き替えようと思ったのですが、test4ができません。test1から3 までは配列を使って書けました。 #include <stdio.h> main() { char s[10]; char *p; strcpy(s, "ABCDE"); p=s; printf("------test1\n"); printf("s=%s p=%s\n", s, p); printf("------test2\n"); putchar(*p); putchar(*(p+1)); putchar(*(p+2)); putchar('\n'); printf("------test3\n"); *p='m'; *(p+1)='n'; printf("s=%s\n", s); printf("------test4\n"); while(*p) { *p=*p+1; ++p; } printf("s=%s\n", s); } この最後のtest4を配列で書くとどうなるのでしょうか。質問文が長くて申し訳ないのですが、お願いいたします。

  • ポインタです

    #include <stdio.h> char *msg = "This is an apple."; void exchange(char *); int main(void){ char *mm = "This is a test."; char *p = msg; printf("%s\n", p);//This is an apple. p = mm; printf("%s\n", p);//This is a test. exchange(p); printf("%s\n", p); return 0; } void exchange(char *q){ q[0] = 't'; } としたら"This is a test." が "this is a test." に変わっているはずなんですがCygwinでの表示は Segmentation fault (core dumped)と表示されてしまいます・・・ なにが原因なんでしょうか?

  • 文字列とポインタの問題です。

    #include<stdio.h> int f(char *s); int main(void){ char*str="nasida Institute of Technology"; int i; i=f(str); printf("%s:%d\n",str,i); return 0; } int f(char *s) { int j=0; while(*s!='\0'){ if(*s=='t'){ j++; } s++; } return j; } このプログラムの答えが3になるんですが、if文のとこの動作がよく分からないので、よろしくお願いします。