VS2005でMFCアプリケーションを作成していますが、CStringを
使わずに処理しようと思っています。
charの配列の末尾から半角空白と改行コード(\r\n)を削除するのに
下のコードを使っていました。
TrimRigth(char* pcRec)
{
long lCnt;
lCnt = strlen(pcRec)-1;
for(long l=lCnt;l>=0;l--){
if(pcRec[l] == ' '){
pcRec[l] = '\0';
}else if(pcRec[l] == '\n'){
pcRec[l] = '\0';
}else if(pcRec[l] == '\r'){
pcRec[l] = '\0';
}else{
break;
}
}
}
これをUNICODE対応のプログラムで使おうと思い次のように修正しました。
( _T()で括っているのは試行錯誤時の名残です)
TrimRigth(WCHAR* pcRec)
{
long lCnt;
lCnt = wcslen(pcRec)-1;
for(long l=lCnt;l>=0;l--){
if(pcRec[l] == ' '){
pcRec[l]=_T('\0');
}else if(pcRec[l] == _T('\n')){
pcRec[l]=_T('\0');
}else if(pcRec[l] == _T('\r')){
pcRec[l]=_T('\0');
}else{
break;
}
}
}
この処理だと、半角空白は削除されるのですが改行コードは削除
されませんでした。
エディットボックス内の改行コード"\r\n"では0x1000が入ってくるし
テキストファイルから取得したデータでは、0x10が入っているのに
なぜか「}else if(pcRec[l] == _T('\n')){」ここにヒットしてくれません。
仕方がないので現在は下のようにしています。
}else if(pcRec[l] == 4096){ // 16進の0x1000
}else if(pcRec[l] == 10){ // 16進の0x0a
}else if(pcRec[l] == 13){ // 16進の0x0d
UNICODEの場合は、2バイトで1文字というのは分かっているのですが
この場合、\r\nのコードは「0D 00 0A 00」という感じで入っていて
0x1000とはこの2バイト分を見ているから、「0A 00」がそういう風に見え
ているのだと思います。(半角空白が1バイトで見えているのは説明できませんが)
そこで質問なんですが、UNICODEの2バイト1文字の1文字ずつ比較するには
どうしたら良いのでしょうか?
よろしくお願いします。
TCHAR で切り替えるのではなくて常に UNICODE にしたいの?
ならば if (c==L'\n') で OK
というか _T('x') をすべて L'x' に置き換えるといい。
お試しコード
#include <stdio.h>
#include <string.h>
int main() {
wchar_t const text[]=L"a\nb\r\n機能\n";
size_t i, n=wcslen(text);
for (i=0; i<n; ++i) {
printf("%04X ", text[i]);
if (text[i]==L'\r') printf("CR ");
if (text[i]==L'\n') printf("LF ");
}
return 0;
}
tetrapodさん、回答ありがとうございます。
色々やってみたのですが、ファイルから読み込んだ
改行コード(\r\n)は
if (text[i]==L'\r')
if (text[i]==L'\n')
これにヒットするようになりました。
しかし、エディットボックスの改行のみの行に入って
いる改行コードはやはりダメでした。
不思議なのは、「文字+改行」だと改行コードは付加されていないのに
「改行」のみだと改行コード(0x1000)が入ってきます。
UNICODEコンパイル時のエディットボックスの改行はマルチバイトの
時と違うんですかね。。。
もしかしたら改行コードではないのかもしれませんが、
エディットボックスの改行は
}else if(pcRec[l] == 4096){ // 16進の0x1000
これで削除するようにしました。
まだ作業中ですので、他に何か情報がありましたら、よろしくお願いします。
エディットボックスの値をどのように取得しているのでしょうか?
UNICODEコンパイルでも改行は\r\nだと思うのですが。
>UNICODEコンパイルでも改行は\r\nだと思うのですが。
そうですよね、だからコレは改行コードではないような気がしてきています。
改行のみの行にしか入ってきませんし。
エディットボックスの行データの取得は以下のようにしています。
CEdit m_Edit05; // 本当はヘッダー定義
TCHAR wzBuff[2048];
long lMax;
lMax = m_Edit05.GetLineCount();
for(long l=0L;l<lMax;l++){
memset(wzBuff, '\0', sizeof(wzBuff));
m_Edit05.GetLine(l, wzBuff, sizeof(wzBuff));
TrimRight(wzBuff); // これが例の関数
}
CEdit::GetLineの仕様みたいです。
http://msdn2.microsoft.com/ja-jp/library/7775836w(VS.80).aspx
lpszBuffer
コピーされる行を受け取るバッファへのポインタ。バッファの最初のワードには、バッファにコピーできる最大バイト数を指定します。
バッファの最初のワード値が上書きされないままゴミになってるのではないでしょうか。
戻り値で実際にコピーされた文字数を調べる必要がありそうです。
subaruさん、ありがとうございます。
正体不明な値の対応をするよりも、GetLine()の戻り値を見て
処理をしないようする方が正しいと思いますので
GetLine()の戻り値が0の場合は処理しないようにしました。
これで、スッキリしました。
ありがとうございます。
ツイート | ![]() |