📄 fstream_test.cpp
字号:
#include <string>#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)# include <fstream># include <iostream># include <iomanip># include <sstream># include <vector># include <stdexcept>#include <stdio.h># include "full_streambuf.h"# include "cppunit/cppunit_proxy.h"# if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)using namespace std;# endif//The macro value gives approximately the generated file//size in Go//#define CHECK_BIG_FILE 4# if (!defined(STLPORT) && (defined (__GNUC__) && (__GNUC__ > 3))) || \ (defined (STLPORT) && !defined (_STLP_NO_CUSTOM_IO) && !defined (_STLP_NO_MEMBER_TEMPLATES) && \ !((defined (_STLP_MSVC) && (_STLP_MSVC < 1300)) || \ (defined (__GNUC__) && (__GNUC__ < 3)) || \ (defined (__SUNPRO_CC)) || \ (defined (__DMC__) && defined (_DLL))))# define DO_CUSTOM_FACET_TEST# endif//// TestCase class//class FstreamTest : public CPPUNIT_NS::TestCase{ CPPUNIT_TEST_SUITE(FstreamTest); CPPUNIT_TEST(output); CPPUNIT_TEST(input); CPPUNIT_TEST(input_char); CPPUNIT_TEST(io); CPPUNIT_TEST(err); CPPUNIT_TEST(tellg); CPPUNIT_TEST(tellp); CPPUNIT_TEST(seek); CPPUNIT_TEST(buf); CPPUNIT_TEST(rdbuf); CPPUNIT_TEST(streambuf_output); CPPUNIT_TEST(win32_file_format); CPPUNIT_TEST(null_stream);# if defined (STLPORT) && (defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS)) CPPUNIT_IGNORE;# endif CPPUNIT_TEST(null_buf);# if !defined (STLPORT) || !defined (_STLP_WIN32) CPPUNIT_TEST(offset);# endif# if defined (CHECK_BIG_FILE) CPPUNIT_TEST(big_file);# endif# if !defined (DO_CUSTOM_FACET_TEST) CPPUNIT_IGNORE;# endif CPPUNIT_TEST(custom_facet); CPPUNIT_TEST_SUITE_END(); protected: void output(); void input(); void input_char(); void io(); void err(); void tellg(); void tellp(); void seek(); void buf(); void rdbuf(); void streambuf_output(); void win32_file_format(); void null_stream(); void null_buf();# if !defined (STLPORT) || !defined (_STLP_WIN32) void offset();# endif void custom_facet();# if defined (CHECK_BIG_FILE) void big_file();# endif};CPPUNIT_TEST_SUITE_REGISTRATION(FstreamTest);//// tests implementation//void FstreamTest::output(){ ofstream f( "test_file.txt" ); f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef"; CPPUNIT_ASSERT (f.good()); // CPPUNIT_ASSERT( s.str() == "1\n2\nabcd\nghk lm\nabcd ef" );}void FstreamTest::input(){ { ifstream f( "test_file.txt" ); int i = 0; f >> i; CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( i == 1 ); double d = 0.0; f >> d; CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( d == 2.0 ); string str; f >> str; CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( str == "abcd" ); char c; f.get(c); // extract newline, that not extracted by operator >> CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( c == '\n' ); getline( f, str ); CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( str == "ghk lm" ); getline( f, str ); CPPUNIT_ASSERT( f.eof() ); CPPUNIT_ASSERT( str == "abcd ef" ); }#if defined (STLPORT) && !defined (_STLP_USE_WIN32_IO) { ifstream in("/tmp"); if (in.good()) { string s; getline(in, s); CPPUNIT_ASSERT( in.fail() ); } }#endif}void FstreamTest::input_char(){ char buf[16] = { 0, '1', '2', '3' }; ifstream s( "test_file.txt" ); s >> buf; CPPUNIT_ASSERT( buf[0] == '1' ); CPPUNIT_ASSERT( buf[1] == 0 ); CPPUNIT_ASSERT( buf[2] == '2' );}void FstreamTest::io(){ basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); CPPUNIT_ASSERT( f.is_open() ); f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef"; // f.flush(); f.seekg( 0, ios_base::beg ); int i = 0; f >> i; CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( i == 1 ); double d = 0.0; f >> d; CPPUNIT_ASSERT( d == 2.0 ); string s; f >> s; CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( s == "abcd" ); char c; f.get(c); // extract newline, that not extracted by operator >> CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( c == '\n' ); getline( f, s ); CPPUNIT_ASSERT( f.good() ); CPPUNIT_ASSERT( s == "ghk lm" ); getline( f, s ); CPPUNIT_ASSERT( !f.fail() ); CPPUNIT_ASSERT( s == "abcd ef" ); CPPUNIT_ASSERT( f.eof() );}void FstreamTest::err(){ basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); CPPUNIT_ASSERT( f.is_open() ); int i = 9; f << i; CPPUNIT_ASSERT( f.good() ); i = 0; f.seekg( 0, ios_base::beg ); f >> i; CPPUNIT_ASSERT( !f.fail() ); CPPUNIT_ASSERT( i == 9 ); f >> i; CPPUNIT_ASSERT( f.fail() ); CPPUNIT_ASSERT( f.eof() ); CPPUNIT_ASSERT( i == 9 );}void FstreamTest::tellg(){ { // bogus ios_base::binary is for Wins ofstream of("test_file.txt", ios_base::out | ios_base::binary | ios_base::trunc); CPPUNIT_ASSERT( of.is_open() ); for (int i = 0; i < 50; ++i) { of << "line " << setiosflags(ios_base::right) << setfill('0') << setw(2) << i << "\n"; CPPUNIT_ASSERT( !of.fail() ); } of.close(); } { // bogus ios_base::binary is for Wins ifstream is("test_file.txt", ios_base::in | ios_base::binary); CPPUNIT_ASSERT( is.is_open() ); char buf[64]; // CPPUNIT_ASSERT( is.tellg() == 0 ); streampos p = 0; for (int i = 0; i < 50; ++i) { is.read(buf, 0); CPPUNIT_ASSERT( is.gcount() == 0 ); CPPUNIT_ASSERT( is.tellg() == p ); is.read( buf, 8 ); CPPUNIT_ASSERT( !is.fail() ); CPPUNIT_ASSERT( is.gcount() == 8 ); p += 8; } } { // bogus ios_base::binary is for Wins ifstream is("test_file.txt", ios_base::in | ios_base::binary); CPPUNIT_ASSERT( is.is_open() ); streampos p = 0; for (int i = 0; i < 50; ++i) { CPPUNIT_ASSERT( !is.fail() ); is.tellg(); CPPUNIT_ASSERT( is.tellg() == p ); p += 8; is.seekg( p, ios_base::beg ); CPPUNIT_ASSERT( !is.fail() ); } } { // bogus ios_base::binary is for Wins ifstream is("test_file.txt", ios_base::in | ios_base::binary); CPPUNIT_ASSERT( is.is_open() ); streampos p = 0; for (int i = 0; i < 50; ++i) { CPPUNIT_ASSERT( is.tellg() == p ); p += 8; is.seekg( 8, ios_base::cur ); CPPUNIT_ASSERT( !is.fail() ); } }}void FstreamTest::tellp(){ { ofstream o( "test_file.txt" ); o << "123456"; CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(6) ); CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(6) ); } { ofstream o( "test_file.txt" ); o << "123456789"; CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(9) ); CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(9) ); } /* According to the standard ofstream o( "test_file.txt", ios_base::app | ios_base::out ) should give the same effect as fopen( "test_file.txt", "a" ). Problem is fopen( "test_file.txt", "a" ) has a bit different behaviour on different platforms, and this difference is not covered by specification. After fopen( "test_file.txt", "a" ) in this context ftell( f ) == 9 for Linux and Mac OS X (I expect the same for others POSIX-like platforms too); on Windows (independently from version?) ftell( f ) == 0, i.e. write pointer not shifted to EOF (but shifted to EOF just before write, as described in the specs). It isn't specifications violation, neither for Linux and Mac OS X nor for Windows. The code below is intended to demonstrate ambiguity (dependance from fopen implementation). */ { #ifdef WIN32 //In Windows, stlport and fopen use kernel32.CreateFile for open. //File position is at BOF after open, unless we open with ios_base::ate long expected_pos = 0; #else //On UNIX flavours, stlport and fopen use unix's open //File position is at EOF after open // //3rd possible scenario, "other platforms" - _STLP_USE_STDIO_IO //stlport uses fopen here. This case may fail this test, since the file position after //fopen is implementation-dependent long expected_pos = 9; #endif ofstream o( "test_file.txt", ios_base::app | ios_base::out ); CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(expected_pos) ); CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(expected_pos) ); } { // for reference, to test fopen/ftell behaviour in append mode: #ifdef WIN32 long expected_pos = 0; #else long expected_pos = 9; #endif FILE* f = fopen( "test_file.txt", "a" ); CPPUNIT_CHECK( ftell( f ) == expected_pos ); fclose( f ); } { //In append mode, file is positioned at EOF just before a write. // After a write, file is at EOF. This is implementation-independent. ofstream o( "test_file.txt", ios_base::app | ios_base::out ); o << "X"; CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(10) ); CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(10) ); }}void FstreamTest::buf(){ fstream ss( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc ); ss << "1234567\n89\n"; ss.seekg( 0, ios_base::beg ); char buf[10]; buf[7] = 'x'; ss.get( buf, 10 ); CPPUNIT_ASSERT( !ss.fail() ); CPPUNIT_ASSERT( buf[0] == '1' ); CPPUNIT_ASSERT( buf[1] == '2' ); CPPUNIT_ASSERT( buf[2] == '3' ); CPPUNIT_ASSERT( buf[3] == '4' ); CPPUNIT_ASSERT( buf[4] == '5' ); CPPUNIT_ASSERT( buf[5] == '6' ); CPPUNIT_ASSERT( buf[6] == '7' ); // 27.6.1.3 paragraph 10, paragraph 7 CPPUNIT_ASSERT( buf[7] == 0 ); // 27.6.1.3 paragraph 8 char c; ss.get(c); CPPUNIT_ASSERT( !ss.fail() ); CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 10, paragraph 7 ss.get(c); CPPUNIT_ASSERT( !ss.fail() ); CPPUNIT_ASSERT( c == '8' );}void FstreamTest::seek(){ { // Test in binary mode: { fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc ); CPPUNIT_ASSERT( s ); s << "1234567890\n"; CPPUNIT_ASSERT( s ); } char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' }; fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary ); CPPUNIT_ASSERT( s ); int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) ); CPPUNIT_CHECK( chars_read == 11 ); CPPUNIT_CHECK( b1[9] == '0' ); CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( 0, ios_base::cur ) == fstream::pos_type(chars_read) ); CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( -chars_read, ios_base::cur ) == fstream::pos_type(0) ); char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' }; CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 10 ) == 10 ); CPPUNIT_CHECK( b2[9] == '0' ); } { // Test in text mode: { fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); CPPUNIT_ASSERT( s ); s << "1234567890\n"; CPPUNIT_ASSERT( s ); } char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' }; fstream s( "test_file.txt", ios_base::in | ios_base::out ); CPPUNIT_ASSERT( s ); int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) ); CPPUNIT_CHECK( chars_read == 11 ); CPPUNIT_CHECK( b1[9] == '0' ); fstream::pos_type pos = s.rdbuf()->pubseekoff(0, ios_base::cur); // Depending on how '\n' is written in file, file position can be greater or equal to the number of chars_read read. streamoff offset = pos; CPPUNIT_ASSERT( offset >= chars_read ); offset = s.rdbuf()->pubseekoff( -offset, ios_base::cur ); CPPUNIT_ASSERT( offset == 0 ); char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' }; CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 5 ) == 5 ); CPPUNIT_CHECK( b2[4] == '5' ); pos = s.rdbuf()->pubseekoff(0, ios_base::cur); CPPUNIT_ASSERT( pos == fstream::pos_type(5) ); CPPUNIT_ASSERT( s.rdbuf()->pubseekoff(-5, ios_base::cur) == fstream::pos_type(0) ); }#if !defined (STLPORT) || \ (!defined (_STLP_NO_WCHAR_T) && defined (_STLP_USE_EXCEPTIONS)) { // Test with a wariable encoding: locale loc; try { locale tmp(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>(".UTF8")); loc = tmp; } catch (const runtime_error&) { // Localization no supported so no test: return; } { wfstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); CPPUNIT_ASSERT( s ); s.imbue(loc); CPPUNIT_ASSERT( s ); s << L"1234567890\n"; CPPUNIT_ASSERT( s ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -