- ベストアンサー
文字列の処理
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>とても難しいソースなので、もう少ししてからでないと そうですね。前回のソースは汎用的なソースですね。 何文字入力しようとも(たとえ1万文字でも問題ありません)、「始めの文字」と「最後の文字」を削除するというプログラムです。 汎用性を消して、今回の目的により絞るのであれば、以下のようにするのが常套手段であり、一番スマートでしょう。 C++プログラマなら、ほとんど次のソースで見解が一致するはずです。 #include <string> #include <iostream> using namespace std; void main() { string s; cin >> s; cout << s.substr(2,6); // 「2byte目」から「6byte分」の長さを表示 }
その他の回答 (5)
- zonbie
- ベストアンサー率27% (3/11)
cockyさんの補足について まず、ポインタを理解する必要があります。 strncpy( y, x+2, 6 ); 引数がポインタなので、x[2] を指しています。 つまり、strncpy( y, x, 6 ); の場合 x は、 x[0] を示しています。 ↓の様に書くことも出来ます。意味は同じです。 strncpy( y, &x[2], 6 ); これでわかりますか?
補足
ポインタのことが分かってないんです。 *p ポインタが指しているの (自身:あり) p ポインタ自身の値 (自身:なし) &p これがよく分かりません。 strncpy( y, x+2, 6 ); の x+2 が x[2] を指しているというのは今理解できました。 strncpy( y, &x[2], 6 ); という書き方もできるというのが分かりませんでした。 どちらかというと strncpy( y, *x[2], 6 ); なんじゃないのかなー と思ってしまいます。 & という文字をあまり見ていないからかもしれません。 でもここで、x+2 というのは &x[2] と同じことだ というふうに記憶しました。 ありがとうございます。
- kokucho81
- ベストアンサー率61% (157/255)
むつかしいところですね。 実はC/C++はこんな簡単なことも統一的な答えが出ないようなヘロイ言語です。 システム記述とか、何万行もの大掛かりなプログラムには向いていますが、個人使用で、文字列処理を中心とするアプリを組むならPerl言語などの方がよほどか将来のためかも。。。 といってもまぁ、人を魅了するような魅力ある言語ではありますが。。。(私も大好きですし♪) さて、ご質問のないようですが。。。 #include <string> #include <iostream> using namespace std; int main(void) { string s; cin >> s; int w_byte=sizeof(wchar_t); // 日本語の一文字の大きさ for (int i=w_byte; i<s.size()-w_byte; i++) { cout << s[i]; } return 0; } という妥協案ぐらいになるのではないでしょうか? wstring型がちゃんとstring型とどうレベルでiostreamに対応していれば、3行程度で汎用的に書けるのですが、たぶんそんな完成度の高いコンパイラはGNU、VC++系、BC++系含め、ほとんどないと思いますので、上記のものとなります。 (bcc系を使用なされておられるようなので、「少し古い系」も紹介しておきます) #include <cstring.h> #include <iostream.h> int main(void) { string s; cin >> s; int w_byte=sizeof(wchar_t); // 日本語の一文字の大きさ for (int i=w_byte; i<s.length()-w_byte; i++) { cout << s[i]; } return 0; }
お礼
2つのソースはどっちとも for (int i=w_byte; ~ という行で 警告 W8012 test.cpp 10: 符号付き値と符号なし値の比較(関数 main() ) という警告が表示されたけど、3文字の抜き出しに成功しました。 とても難しいソースなので、もう少ししてからでないと 理解できそうにないけど、高級そうなソースなのでうれしいです。 ありがとうございます。
- zonbie
- ベストアンサー率27% (3/11)
回答です。 #include <iostream.h> main(){ char x[11]; //ここで あいうえお という5文字を入力 cin >>x; for(int i=2;i<8;i++){ cout << x[i]; } } ただしこれは 日本語5文字を入れる為に最低必要なメモリしか用意してません。(x[11] → 5文字 × 2バイト + NULL = 11) for文で x[2]~x[7] を表示してます。 ※これは、あくまでも上記質問のケースの場合に限った 回答サンプルで、他の方の回答のような実用的なものではありません。
お礼
bcc5.5でできました。 ありがとうございます。 こういう方法もあるということが勉強になりました。
- selenity
- ベストアンサー率41% (324/772)
文字列を取り扱う際は文字型の配列または文字型への ポインタを使用します。 つまり、 char array[256]; や char *buffer; buffer=(char*)malloc(sizeof(char)*256); のように文字列の代入先のメモリ領域を あらかじめ確保しておく必要があります。 Windowsはメモリ管理がかないいかげんなので メモリ確保していない変数にも正常に代入できてしまいます。 また、日本語は1文字で2Byte消費しますので 上記の例の場合、127文字までしか使用できません。 cockyさんのサンプルでy[6]="\0";となってますが、 これはy[6]='\0';の記述ミスですね。
お礼
グッドアドバイス。
- cocky
- ベストアンサー率57% (232/402)
そもそもchar x[1]だと、配列が短すぎてまともに動かないと思いますが。 ま、それはさておき、配列が十分な長さがあるとして考えると、ひらがな文字は2Byteコードなので、 #include <string.h> #include <iostream.h> main() { char x[256], y[256]; cin >> x; strncpy( y, x+2, 6 ); y[6] = "\0"; cout << y; } とでもすれば大丈夫では? #ホントはmallocとか使って、メモリに無駄がないように処理した方がいいんでしょうけど。
お礼
char x[1] だと、配列が短か過ぎでエラーになるかと 思っていたら、エラーにならない場合もあるから、 最低限の char x[1] にしたんです。 char の値を大きくとれば安心だけど、大きく取り過ぎて 使われない部分があるともったいないなーと思ってい たりするんです。 ソースありがとうございます。 でも、bcc5.5でコンパイルエラーでした。 #include <string.h> #include <iostream.h> main() { char x[256], y[256]; cin >> x; strncpy( y, x+2, 6 ); y[6] = "\0"; cout << y; } エラー E2034 test.cpp 8: 'char *' 型は 'char' 型に変換できない(関数 main() ) *** 1 errors in Compile ***
補足
selenityさんの情報にあったように y[6] = '\0'; に直したらできました。 ありがとうございます。 簡単なソースだけど strncpy( y, x+2, 6 ); の x+2 というのが理解できませんでした。 難しいです。
関連するQ&A
- 無限ループで出力ストリームが表示されないのはなぜですか?
次のソースコードをVC++で実行したところ、入力の表示ができませんでした。 でも、無限ループを削除すると、正常に表示されます。 非常に基本的な質問かもしれませんが、理由がわかりません。 ご存知でしたら教えてください。よろしくお願い致します。 #include <iostream.h> int main() { char ss[80]; cout << "何か入力してください:"; cin >> ss; cout << "入力したのは[" << ss << "]です\n"; for(;;) { } }
- ベストアンサー
- C・C++・C#
- 入力文字数がでません。
C++です。以下を実行したのですが、実行結果に改行数は出るが文字数がでません。お願いします。 #include <iostream.h> int main(void) { char c; int ccount = 0; int ncount = 0; while (cin.get(c)) { ccount++; if (c == '\n') ncount++; } cout << "文字数=" << ccount << '\n'; cout << "改行数=" << ncount << '\n'; return (0); }
- ベストアンサー
- C・C++・C#
- C++の関数
関数の課題が出たんですが分からないので教えてください。 第1引数と第2引数はchar型の1元配列であり、これら2つの配列(文字列)を連続して表示する関数catstringがあるものとする。 ただし第2引数にはデフォルトの文字列"あいうえお"が設定されている。main関数からキーボード入力で2つの文字列を取得し、 catstringの第1引数のみに文字列が渡される場合と第1、2引数ともに文字列が与えられるプログラムを作成せよ。 やってみましたがエラーが出てしまいます。 #include <iostream> #include <cstdlib> using namespace std; char catstring(char,char="あいうえお"); int main() { char a,b; cin>>a; cin>>b; cout<<catstring(a)<<endl; cout<<catstring(a,b)<<endl; return EXIT_SUCCESS; } char catstring(char x,char y) { char s; s=x+y; return(s); }
- ベストアンサー
- C・C++・C#
- DOS画面をプリンタ出力
MS-DOSプロンプトの画面をプリンタに出力されるプログラムを 作ろうと思いました。 #include <iostream.h> main(){ char ppp; cout << "pの入力でプリントします"; cin >> ppp; if (ppp=='p'){ cout << "pが入力された"; ここでプリンタ出力命令 } } プリンタ出力命令はどういう命令文を書ければいいのか 教えてください。
- ベストアンサー
- C・C++・C#
- strcat で型が合わない
#include <iostream.h> main(){ char x[15]; for(int i=0;i<15;i++) x[i]=i+49; for(int i=0;i<15;i++){ cout <<x[i]; }; } 9より先の文字化けは考えないとして、 char x[15]; というのは適切ですか? 16個目の要素になる x[15] には、文字列の最後の \0 が入ると思って char x[14]; にしなかったんです。 コンパイルして実行すると 123456789... となるけど、 2桁にしたいんです。半角スペースを使いたいんです。 1 2 3 4 5... のようにしたいんです。 そのように表示する方法は色々あるけど、 文字列の配列でやる場合の方法が知りたいんです。 #include <iostream.h> main(){ char x[15]; char y=" " for(int i=0;i<15;i++){ x[i]=strcat( y,(char)(i+49) ); }; for(int i=0;i<15;i++){ cout <<x[i]; }; } ↑のようなことやってみたけど、型が合わないとかで うまくできませんでした。 strcat とか strncpy は難しいです。 正しいソースを教えてください。
- ベストアンサー
- C・C++・C#
- getlineについて
現在getlineを用いてプログラムを作成しようとしているのですが、例えば #include <iostream> using std::cin; using std::cout; using std::endl; int main(){ char buffer[81]; while(!cin.eof()){ cin.getline(buffer,sizeof(buffer)); cout << buffer << endl; while((!cin.eof())&&cin.fail()){ cin.clear(); cin.ignore(80,'\n'); } } return 0; } というプログラムを作った場合、標準入力から各行を80文字だけ読み込み出力をするわけなんですが、 この80文字という文字制限をなくしたい場合どういった工夫をすればいいのでしょうか?
- ベストアンサー
- その他(プログラミング・開発)
- プロンプト入力 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 に格納されてしまう。 そうならないためのよい方法があったら教えてください。
- ベストアンサー
- C・C++・C#
- C++で解りません。
C++で #include <iostream.h> int main(void) { int x; int y; cout << "xを入力してください:"; cin >> x; cout << "yを入力してください:"; cin >> y; cout << "x+yは" << x + y << "です。\n"; return 0; } ----------- で、 エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) とでます。どこがおかしいのか解りません。
- ベストアンサー
- C・C++・C#
補足
便利な関数を教えてもらいました。 ありがとうございます。 すぐに理解できました。 特別な関数を使う時に、#include 以外のものを宣言する というのは初めて見ました。