2013-12-15 78 views
1

就在:ifstream的和oftream問題

int size = getFileSize(path); //Listed below 
ifstream fs(path, ios::in); 
ofstream os(path2, ios::out); 

//Check - both streams are valid 
char buff[CHUNK_SIZE]; //512 

while (size > CHUNK_SIZE) 
{ 
    fs >> buff; 
    os << buff; 
    size -= CHUNK_SIZE; 
} 
char* dataLast = new char[size]; 
fs>>dataLast; 
os<<dataLast; 
fs.close(); 
os.close(); 

//發現在SO,工作在PATH2精細

int getFileSize(string path) 
{ 
FILE *pFile = NULL; 

if (fopen_s(&pFile, path.c_str(), "rb")) 
{ 
    return 0; 
} 

fseek(pFile, 0, SEEK_END); 
int Size = ftell(pFile); 
fclose(pFile); 
return Size; 
} 

文件已損壞,小於1 KB。 (初始文件爲30Kb); 我不需要建議如何複製文件,我很好奇這個例子有什麼問題。

+1

沒有建議,但用'>>'閱讀是你現在不想的 – P0W

+0

@ P0W非常感謝。 –

回答

3

首先一個重要警告:決不(如真的從來沒有)使用char*格式的輸入操作,而不設置width()!你打開一個緩衝區溢出。這基本上是編寫gets()的C++版本,這個版本已經足夠壞,無法從C標準中刪除(不僅僅是棄用)!如果您在使用格式化輸入與char*堅持(通常你是好得多使用std::string),設置寬度,如:

char buffer[512]; 
in >> std::setw(sizeof(buffer) >> buffer; 

OK,這個出路:看來你真的想修改兩處重要的事情:

  1. 你可能不想使用格式化輸入,即operator>>():格式化的輸入操作員開始跳過空白。當讀入char*時,它也會在到達空格時停止(或者當width()在讀取很多字符和靜止空間來存儲終止零時非零時;請注意,在這些讀取之後,設置width()將被重置爲0 )。也就是說,您可能想要使用未格式化的輸入,例如in.read(buffer, sizeof(buffer)),其將in.gcount()設置爲實際讀取的字符的數量,其可能小於大小參數,例如在流的末尾。
  2. 您可能應該在std::ios_base::binary模式下打開文件。儘管在一些系統(例如,POSIX系統)上,在文本模式閱讀的某些系統上合併一個行結束序列(例如,在Windows上輸入\r\n,輸入行結尾字符\n。同樣,在文本模式下編寫\n時,它將被某個系統上的行結束序列替換,即,您可能還希望以文本模式打開輸出流。
1

當使用字符串(如buff從庫的角度來看)時,輸入和輸出操作符僅讀取空格分隔的單詞。

如果要讀取塊,然後使用​​,並使用std::istream::gcount來獲取實際讀取的字節數。然後用std::ostream::write寫。

如果文件中的數據是二進制的,則應該使用binary open mode