C++において、テキストファイルから文字を読み込み、10バイト目の文字を取得するロジックを作っています。
流れとしてはifstreamでファイル開き、getlineで一行ずつ読み込んだ内容を
string型の変数に結合しています。
その結合した文字列の10文字目ではなく10バイト目の文字が知りたいのですが、
どのような手段がありますでしょうか?
ご教授いただければ幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/01/26 10:36
回答5件
0
C++初心者なので、コーディング方法の拙い点はご容赦ください…
他の回答者さんもご指摘のように、文字コードの種類が決まらないと具体的なアルゴリズムは決められないですよね。
そこで、文字コードがUTF-8であると仮定して、以下のようなコードを書いてみました。
C++
1#--- 入力ファイルの内容 --- 2$ cat test.txt 3testテスト123! 4てすとTEST試験 5$ 6 7#--- 入力ファイルの文字コードはUTF-8 --- 8$ nkf -guess test.txt 9UTF-8 10$ 11 12#--- サンプルコード --- 13$ cat test.cpp 14#include <string> 15#include <fstream> 16#include <iostream> 17 18using namespace std; 19 20int main() { 21 22 ifstream ifs("test.txt"); 23 24 string str, chr; 25 int lines, char_size, s_byte, e_byte; 26 unsigned char lead; 27 28 lines = 0; // 行番号 29 30 // 一行ずつ読み込んで処理 31 while (ifs && getline(ifs, str)) { 32 printf("%3d : %s\n", ++lines, str.c_str()); 33 34 s_byte = 0; // 文字の最初のバイト位置 35 e_byte = 0; // 文字の最後のバイト位置 36 for (string::iterator it = str.begin(); it != str.end(); it += char_size) { 37 38 lead = *it; 39 40 // 文字のバイト数を判定 41 if (lead < 0x80) { 42 char_size = 1; 43 } else if (lead < 0xE0) { 44 char_size = 2; 45 } else if (lead < 0xF0) { 46 char_size = 3; 47 } else { 48 char_size = 4; 49 } 50 51 s_byte = e_byte + 1; 52 e_byte = s_byte + char_size - 1; 53 chr = str.substr(distance(str.begin(), it), char_size); 54 printf(" %2d - %2d : %s\n", s_byte, e_byte, chr.c_str()); 55 56 // 文字の最後のバイト位置が10バイト目以上になったら次の行へ 57 if (e_byte >= 10) 58 break; 59 60 } 61 62 } 63 64} 65$ 66 67#--- 実行結果 --- 68$ ./a.out 69 1 : testテスト123! 70 1 - 1 : t 71 2 - 2 : e 72 3 - 3 : s 73 4 - 4 : t 74 5 - 7 : テ 75 8 - 10 : ス 76 2 : てすとTEST試験 77 1 - 3 : て 78 4 - 6 : す 79 7 - 9 : と 80 10 - 10 : T 81$
色々な文字コードに対応させるには、各種文字コードに対応した「10バイト目の文字を検出する」関数を事前に用意しておき、入力ファイルの文字コードを(何らかの方法で)判定した上で、対応する関数を呼び出せば良いのではないでしょうか。
投稿2016/01/26 20:40
総合スコア5936
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/01/26 23:52
2016/01/27 01:09
2016/01/27 01:21
2016/01/27 01:52 編集
2016/01/27 02:07
0
前提としてはこういうことですよね。
C++
1/*-------- ファイルの中身 2あいう 3えお 4か 5きくけこ 6----------*/ 7 8string str; 9// ファイルからgetloneで1行ずつ読み込んで連結 10// 結果、strに "あいうえおかきくけこ" が入る
10文字目ではなく10バイト目の文字が知りたいのですが、
どのような手段がありますでしょうか?
C++
1char ch = str[9]; // stringの文字位置は0から始まるので10文字目は[9]
stringクラスは[]演算子をオーバーロードしているので、このように単純に取得したい文字の位置を配列の添え字として指定すれば良いです。
マルチバイト文字云々に関しては、それを判った上でのご質問と解釈します。
投稿2016/01/26 13:29
総合スコア5938
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/01/26 14:15
2016/01/26 14:21
0
こんにちは。
その結合した文字列の10文字目ではなく10バイト目の文字が知りたいのですが、
他バイト文字の場合、10バイト目が他バイト文字の最初のバイトかもしれないし、最後のバイトかもしれません。ですので、文字コードを決めないとアルゴリズムを決定できないように思います。
もし、UTF-8なら、ここをみればアルゴリズムを作れると思います。
10バイト以上読み込み、10バイト目が含まれる文字を表示するのであれば、使われている文字エンコードの1文字の最大バイト数+9バイト以上をifstreamのread()で読んで10バイト目付近を解析すればできるだろうと思います。
投稿2016/01/26 12:37
総合スコア23272
0
対象のテキストファイルから1文字読み取る事は出来ますか?
出来るなら、それを10回繰り返せば良いのではないですか?
バイト単位で考えているのに、なぜ行単位で読み込むのですか?
同じく、string型にするのも理解できません。
ひょっとして、「改行文字はカウントしない」という仕様なのでしょうか?
投稿2016/01/26 12:27
総合スコア711
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
マニピュレータの使い方がよく分かってないのでprintf()にしました^^;
cpp
1~/test/cpptst >./a.out 2a1=ffffffe3, a2=39 3~/test/cpptst >cat tst03.cpp 4#include <iostream> 5#include <string> 6#include <cstdio> 7using namespace std; 8 9int main() 10{ 11 string line1 = "これはテスト用の文字列です"; 12 string line2 = "01234567890123456789"; 13 14 char ans1 = line1.c_str()[9]; 15 char ans2 = line2.c_str()[9]; 16 17 printf("a1=%02x, a2=%02x\n", ans1, ans2); 18 19 return 0; 20} 21~/test/cpptst >
投稿2016/01/26 11:52
編集2016/01/26 11:55総合スコア6851
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。