stringでの日本語の使い方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
Cr
記事: 93
登録日時: 8年前

stringでの日本語の使い方

#1

投稿記事 by Cr » 8年前

c++です。
stringで日本語の文章を入力し、それを逆にして返すというプログラムが書きたかったのですがうまくいきません
入力が「日本語の文章」なら出力は「章文の語本日」としたいです。

コード:

#include<iostream>
#include<string>
using namespace std;

int main(){
	string str;

	while(1){
		cin >> str;
		
		if(str=="END") return 0;
		
		do{
               cout << str.substr(str.size()-1);
               str.erase(str.size()-1);
        }while(!str.empty());
		
		cout <<endl;
		
	}	
}
これをコンパイルして実行したところ英語の分に対しては正しい出力がされましたが日本語では無理でした
たとえば
C言語→鼬セ靴
あいうえお→ィえういあ
漢字とひらがなを使う→、H酒ながらひとz質
といった具合です。
試しにひっくり返さずにそのまま出力する命令を前に入れたところ文字化けは起こりませんでした
確か日本語は英語より使ってる領域が多かった覚えがあり、それが関係しているのだろうと予測しています。
日本語でこの機能を満たすことは可能でしょうか?

アバター
Cr
記事: 93
登録日時: 8年前

Re: stringでの日本語の使い方

#2

投稿記事 by Cr » 8年前

追記です
文字化けしたものをもう一回プログラムにかけてみたらこうなりました
鼬セ靴→C言語
、H酒ながらひとz質→ソ字とひらがなを使う
ィえういあ→いうえお
最初の文字だけはアルファベット以外うまくいかないみたいですが、他の文字は元に戻りました。

non
記事: 1097
登録日時: 9年前

Re: stringでの日本語の使い方

#3

投稿記事 by non » 8年前

SHIFT-JISなら、漢字は2バイトなので、
str.size()-2 にして試してみたら。
注:半角を混ぜると暴走するかも。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: stringでの日本語の使い方

#4

投稿記事 by softya(ソフト屋) » 8年前

wstring他のワイド文字系で統一すれば問題ないと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たかぎ
記事: 328
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: stringでの日本語の使い方

#5

投稿記事 by たかぎ » 8年前

softya(ソフト屋) さんが書きました:wstring他のワイド文字系で統一すれば問題ないと思います。
std::wstringだと処理系に依存しますし、std::u16stringだとサロゲートペアが問題になります。
std::u32stringであれば、次のように、簡単に文字列を反転することができます。

コード:

std:u32string str(U"日本語の文章");
std::reverse(str.begin(), str.end());
ただし、標準入力や標準出力を扱うのはちょっと面倒になります。
(処理系を特定するなら、ほとんどの場合、そう難しくありません)

アバター
みけCAT
記事: 6277
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: stringでの日本語の使い方

#6

投稿記事 by みけCAT » 8年前

とりあえず作ってみました。
► スポイラーを表示
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Cr
記事: 93
登録日時: 8年前

Re: stringでの日本語の使い方

#7

投稿記事 by Cr » 8年前

non さんが書きました:SHIFT-JISなら、漢字は2バイトなので、
str.size()-2 にして試してみたら。
注:半角を混ぜると暴走するかも。
一回試してみました
日本語はうまく行きました!
ただやっぱりアルファベット混ぜると無理ですね…
softya(ソフト屋) さんが書きました: wstring他のワイド文字系で統一すれば問題ないと思います。
マルチバイト自体が初耳でして
一応いろいろ調べてみたのですが…
ちょっと実装するには先が長そうです…
たかぎ さんが書きました: std::wstringだと処理系に依存しますし、std::u16stringだとサロゲートペアが問題になります。
std::u32stringであれば、次のように、簡単に文字列を反転することができます。
同じく初耳です
wstringの方を理解してから調べたいと思います…
みけCAT さんが書きました: とりあえず作ってみました。
何やってるかはなんとなく分かりました
細かい仕組みは分かりませんが…

とりあえずチャットの方で教えていただいた情報も参考に、
先頭からその文字が1バイトかかどうか判断し、その分を別のstringの先頭にひたすら足していくという方法で作ってみました。
文字コードなど、細かいことはまだ分かっていませんが一応実行結果はでました。

コード:

#include<iostream>
#include<string>
#include<Windows.h>
using namespace std;
int main(){
	string str;
	char c;
	while(1){
		cin >> str;
		string answer;
		if(str=="END") return 0;
		do{
			c = str[0];
			if(IsDBCSLeadByte(c)==0){
				answer.insert(0,str.substr(0,1));
				str.erase(0,1);
			}else{
				answer.insert(0,str.substr(0,2));
				str.erase(0,2);
			}
        }while(!str.empty());
		cout <<answer <<endl;
	}	
}
入力 日本語とEnglish
出力 hsilgnEと語本日
入力 あaいiうuえeおo
出力 oおeえuうiいaあ

望む動きはできたので解決としたいと思います
マルチバイト等の単語についてはテスト明けにゆっくり調べたいと思います。
みなさんどうもありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る