ようこそ ゲスト さん、新規登録(無料)して気になる疑問を解決しませんか?

質問

質問者:noname#97178 c++ Base64でファイルをテキストへ変換するプログラムが動かない
困り度:
  • 暇なときにでも
C++で第1引数に指定したファイルを読み込んでBase64でテキストへ変換してコンソールに表示するプログラムをつくりました。しかし結果が途中で途切れてしまったり、変な文字が交端に表示されます。どこが悪いのか教えてください。

ーーーーーーーーーーーーーーーーーーーーーーーーーー

#include <windows.h>
#include <iostream>
#include <fstream>

char* Encode(const char *szStr, int iLens)
{
const char *szB64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char *lpszOutputString; // 結果出力先
int iLen;

int i,j;

if(iLens == -1)
iLen = strlen(szStr);
else
iLen = iLens;

lpszOutputString =
new char[(int)((double)(iLen)*1.5)+10];
for(i = 0,j = 0; i < (iLen - (iLen % 3)); i+=3)
{
lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4) |
((szStr[i+1] & 0xf0) >> 4)];
lpszOutputString[j+2] = szB64[((szStr[i+1] & 0x0f) <<2 ) |
((szStr[i+2] & 0xc0) >> 6)];
lpszOutputString[j+3] = szB64[(szStr[i+2] & 0x3f)];
j += 4;
}
i = iLen-(iLen % 3); // 残りのサイズを計算
switch(iLen % 3)
{
case 2: // 1文字分パディングが必要
{
lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4) |
((szStr[i+1] & 0xf0) >> 4)];
lpszOutputString[j+2] = szB64[((szStr[i+1] & 0x0f) <<2 )];
lpszOutputString[j+3] = szB64[64]; // Pad
lpszOutputString[j+4] = '\0';
}
break;
case 1: // 2文字分パディングが必要
{
lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4)];
lpszOutputString[j+2] = szB64[64]; // Pad
lpszOutputString[j+3] = szB64[64]; // Pad
lpszOutputString[j+4] = '\0';
}
break;
}
lpszOutputString[j+4] = '\0';

return lpszOutputString;
}


int main(int argc,char *argv[]){

std::ifstream fp(argv[1], std::ios::in|std::ios::binary);
std::fstream::pos_type begp, endp;
fp.seekg(0, std::ios_base::end);
endp = fp.tellg();
fp.seekg(0, std::ios_base::beg);
begp = fp.tellg();
int fsize;
fsize = (int)(endp - begp);

char* buff = new char[fsize+1];
std::cout << "ファイルサイズ:" << fsize << std::endl;
fp.read(buff,fsize);
buff[fsize] = '\0';

std::cout <<Encode(buff, -1) << std::endl;

return 0;
}
質問投稿日時:09/10/26 15:32
質問番号:5398098
この質問に対する回答は締め切られました。
最新から表示回答順に表示

回答

 

回答者:hiro_knigh Encode関数内でstrlenを使われていますが、バイナリファイルを読み込んだ場合、0('\0')も立派なデータとなります。
よって、strlenでファイルの大きさを求めることは出来ません。
これが途中で切れてしまう原因と思われます。
あとは、右シフトの問題だと思います。
charは符号付の型なので、右シフトは算術シフトになっていると思われます。
種類:アドバイス
どんな人:専門家
自信:参考意見
回答日時:09/10/26 23:33
回答番号:No.2
この回答へのお礼この回答にお礼をつける(質問者のみ)

回答

 

回答者:Tacosan ぱっと見
・for の範囲がおかしい
・char の右シフトがあやしい
の 2点はある.
char ch = '\x9f';
printf("%d\n", ch >> 1);
の結果が (char を 8ビットと仮定して) どうなるかわかりますか?
種類:アドバイス
どんな人:一般人
自信:参考意見
回答日時:09/10/26 22:56
回答番号:No.1
この回答へのお礼この回答にお礼をつける(質問者のみ)
最新から表示回答順に表示