如何在c ++中的第n行(例如第5行)写入文件? 这是我的尝试:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream stream1("1.txt");
string line ;
ofstream stream2("2.txt");
int lineNumber = 0;
while(getline( stream1, line ) )
{
if (lineNumber == 5)
{
stream2 << "Input" << endl;
lineNumber = 0;
}
lineNumber++;
}
stream1.close();
stream2.close(); return 0;
}
在&#34; 1.txt&#34;,我有“#34;学生&#34;在第4行,现在我想忽略上面的4行并输入单词&#34;输入&#34;在第5行(低于#34;学生&#34;)。当我运行上面的代码时,输出文件是空白的。有任何建议如何解决这个问题?谢谢。
答案 0 :(得分:2)
如果我理解正确,您只需要2.txt中的1.txt的副本,只需将您的个人内容替换为特定的行号。
在你看来,这个词是“输入”。
这里是我从原始代码修改的代码 -
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream stream1("1.txt");
string line ;
ofstream stream2("2.txt");
int lineNumber = 0;
int line_to_replace = 4; //This will replace 5th line
while(getline( stream1, line ) )
{
if (lineNumber == line_to_replace)
{
stream2 << "Input" << endl;
}
else
stream2 << line << endl;
lineNumber++;
}
stream1.close();
stream2.close();
return 0;
}
输入文件(1.txt) -
sdlfknas sdfas sdf g thtr 34t4 bfgndty 45y564 grtg
输出文件(2.txt) -
sdlfknas sdfas sdf g Input 34t4 bfgndty 45y564 grtg
P.S。为了更好地学习和理解编程,我建议不要使用:
using namespace std;
答案 1 :(得分:1)
当你正在阅读第5行时,lineNumber
等于4 b / c,你开始计数为0。
更改if(lineNumber == 5)
到if(lineNumber == 4)
您还遇到一个问题,即您正在设置lineNumber = 0
然后立即递增到1,因此在再次输出之前,您只需计算4行。
答案 2 :(得分:1)
我会创建一个这样的函数......
bool isBlank(string line) {
if (!line.empty()) {
for (auto x: line) {
if (isalnum(x)) {
return false;
}
}
}
return true;
}
如果字符串为空或没有字母数字字符,则返回true。
您可以在getline语句后立即调用此函数。
isalnum 功能在<cctype>
答案 3 :(得分:1)
使用代码后,我设法获得了您想要的输出。这是您的代码的更新版本。
#include <iostream>
#include <fstream>
int main() {
std::ifstream stream1( "1.txt" );
std::string line;
std::ofstream stream2( "2.txt" );
int lineNumber = 1;
while ( getLine( stream1, line ) ) {
if ( lineNumber == 5 ) {
stream2 << "Input" << std::endl;
} else {
stream2 << std::endl;
lineNumber++;
}
}
stream1.close();
stream2.close();
return 0;
}
您必须确保的一件事是,在您的1.txt
中,第4行上有单词student,您必须在文件中的此文本后至少有2个空行。一个简单的输入或回车将做!如果不这样做,while( getline() )
将超出范围且不会读取下一行,并且代码块将永远不会在if()
时输入lineNumber == 5
语句,并且不会打印文本"Input"
到您的stream2
文件流对象。
如果1.txt
文件中的最后一行文字是带有文字字符串Student
的行,这里会发生的是它会将此行文本添加到line
字符串变量中然后代码会将lineNumber
增加到等于5
。下次进入while循环调用getline()
时,它返回false,因为你在EOF
,因为文件中没有更多的文本行要读入,这导致while循环到断开执行并超出范围,if( lineNumber == 5 )
永远不会被调用,因为它嵌套在while
循环的范围内。
答案 4 :(得分:0)
我的第一个回答解决了您的问题并将输出正确地输出到您的文本文件。然而,正如我所提到的,在一行文本中读取while循环并对两个文件流使用相同的计数器并不是很优雅。更准确的方法是简化调试,这样就可以一次读取一行完整的输入文件,并将每行保存到字符串中,同时将字符串存储在向量中。这样,您可以一次解析一行所需的每行文本,并且可以轻松遍历矢量以快速找到您的文本行。您还应该进行检查以确保您的文件存在并且正确打开。
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main() {
std::string strTextFileIn( "1.txt" );
std::ifstream in;
std::string strLine;
std::vector<std::string> vFileContents;
// Open File Stream
in.open( strTextFileIn.c_str(), std::ios_base::in );
// Test To Make Sure It Opened Properly And That It Exists
if ( !in.is_open() ) {
std::cout << "Failed to open file, check to make sure file exists." << std::endl;
return -1;
} else {
while ( !in.eof() ) {
// Get Line Of Text And Save To String
std::getline( in, strLine );
// Push String Into Vector
vFileContents.push_back( strLine );
}
}
// Done With File Close File Stream
if ( in.is_open() ) {
in.close();
}
// Now That We Have Read In The File Contents And Have Saved Each Line Of Text To A String
// And Stored It In Our Container (Vector) We Can Traverse Our Vector To Find Which String
// Matches The Text We Are Looking For Retrive Its Indexed Value And Then Write To Our
// Output File According To Where You Want The Text To Be Written
unsigned index = 0;
const std::string strLookup( "Student" );
for ( unsigned int i = 0; i < vFileContents.size(); i++ ) {
if ( vFileContents[i] == strLookup ) {
// Strings Match We Have Our Indexed Value
index = i;
}
}
// We Want To Write Our Line Of Text 1 Line Past Our Index Value As You Have Stated.
std::string strTextFileOut( "2.txt" );
std::ofstream out;
// Open Our File For Writting
out.open( strTextFileOut.c_str(), std::ios_base::out );
if ( !out.is_open() ) {
std::cout << "Failed To open file.";
vFileContents.clear();
return -1;
} else {
for ( unsigned int i = 1; i <= index; i++ ) {
out << std::endl; // Write Blank Lines
}
// The Text Or String You Want To Write To File
out << "Input" << std::endl;
}
// Done With File Stream
if ( in.is_open() ) {
in.close();
}
// Clear Out Vector
vFileContents.clear();
return 0;
} // main
现在可以通过创建用于处理各种文件流对象类型的类层次结构来简化这一过程,这样您就不必编写此代码来打开,关闭,检查有效性,读取完整文件或在你需要的地方一遍又一遍地排队。这使它模块化。但是,此结构依赖于其他一些类,例如ExceptionHandler
类和Logger
类。下面是一个小型多文件应用程序。
stdafx.h 注意:并非所有这些包含和定义都将在这里使用,但这来自我的一个更大的项目,我只剥离了那些类需要这里,但保留我的标准标题。我删除的唯一内容是&#34; stdafx.h&#34;是什么必须处理OpenGL,OpenAL,Ogg - Vorbis,GLM Libraries&amp;的API
#ifndef STDAFX_H
#define STDAFX_H
#define VC_EXTRALEAN // Exclude Rarely Used Stuff Windows Headers - Windows Only
// Instead of Creating Another File That VS Makes For You "targetver.h"
// I Will Just Append Its Contents Here
#include <SDKDDKVer.h> // Windows Only
#include <Windows.h> // Windows Only
#include <process.h>
#include <tchar.h>
#include <conio.h>
#include <memory>
#include <string>
#include <numeric>
#include <vector>
#include <array>
#include <unordered_map>
#include <queue>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "ExceptionHandler.h"
namespace pro {
enum ReturnCode {
RETURN_OK = 0,
RETURN_ERROR = 1,
};
extern const unsigned INVALID_UNSIGNED;
extern const unsigned INVALID_UNSIGNED_SHORT;
} // namespace pro
#endif // STDAFX_H
<强> stdafx.cpp 强>
#include "stdafx.h"
namespace pro {
const unsigned INVALID_UNSIGNED = static_cast<const unsigned>( -1 );
const unsigned INVALID_UNSIGNED_SHORT = static_cast<const unsigned short>( -1 );
} // namespace pro
<强> ExceptionHandler.h 强>
#ifndef EXCEPTION_HANDLER_H
#define EXCEPTION_HANDLER_H
namespace pro {
class ExceptionHandler sealed {
private:
std::string m_strMessage;
public:
explicit ExceptionHandler( const std::string& strMessage, bool bSaveInLog = true );
explicit ExceptionHandler( const std::ostringstream& strStreamMessage, bool bSavedInLog = true );
// ~ExceptionHandler(); // Default Okay
// ExeptionHandler( const ExceptionHandler& c ); // Default Copy Constructor Okay & Is Needed
const std::string& getMessage() const;
private:
ExceptionHandler& operator=( const ExceptionHandler& c ); // Not Implemented
}; // ExceptionHandler
} // namespace pro
#endif // EXCEPTION_HANDLER_H
<强> ExceptionHandler.cpp 强>
#include "stdafx.h"
#include "ExceptionHandler.h"
#include "Logger.h"
namespace pro {
ExceptionHandler::ExceptionHandler( const std::string& strMessage, bool bSaveInLog ) :
m_strMessage( strMessage ) {
if ( bSavedInLog ) {
Logger::log( m_strMessage, Logger::TYPE_ERROR );
}
}
ExceptionHandler::ExceptionHandler( const std::ostringstream& strStreamMessage, bool bSaveInLog ) :
m_strMessage( strStreamMessage.str() ) {
if ( bSaveInLog ) {
Logger::log( m_strMessage, Logger::TYPE_ERROR );
}
}
const std::string& ExceptionHandler::getMessage() const {
return m_strMessage;
}
} // namespace pro
BlockThread.h - 需要记录器
#ifndef BLOCK_THREAD_H
#define BLOCK_THREAD_H
namespace pro {
class BlockThread sealed {
private:
CRITICAL_SECTION* m_pCriticalSection;
public:
explicit BlockThread( CRITICAL_SECTION& criticalSection );
~BlockThread();
private:
BlockThread( const BlockThread& c ); // Not Implemented
BlockThread& operator=( const BlockThread& c ); // Not Implemented
}; // BlockThread
} // namespace pro
#endif // BLOCK_THREAD_H
<强> BlockThread.cpp 强>
#include "stdafx.h"
#include "BlockThread.h"
namespace pro {
BlockThread::BlockThread( CRTICAL_SECTION& criticalSection ) {
m_pCriticalSection = &criticalSection;
EnterCriticalSection( m_pCriticalSection );
}
BlockThread::~BlockThread() {
LeaveCriticalSection( m_pCriticalSection );
}
} // namespace pro
Logger
是 Singleton
,因为在您的应用程序运行时,您只需要一个实例。
<强> Singleton.h 强>
#ifndef SINGLETON_H
#define SINGLETON_H
namespace pro {
class Singleton {
public:
enum SingletonType {
TYPE_LOGGER = 0, // Must Be First!
// TYPE_SETTINGS,
// TYPE_ENGINE,
};
private:
SingletonType m_eType;
public:
virtual ~Singleton();
protected:
explicit Singleton( SingletonType eType );
void logMemoryAllocation( bool isAllocated ) const;
private:
Singleton( const Singleton& c ); // Not Implemented
Singleton& operator=( const Singleton& c ); // Not Implemented
}; // Singleton
} // namespace pro
#endif // SINGLETON_H
<强> Singleton.cpp 强>
#include "stdafx.h"
#include "Logger.h"
#include "Singleton.h"
//#include "Settings.h"
namespace pro {
struct SingletonInfo {
const std::string strSingletonName;
bool isConstructed;
SingletonInfo( const std::string& strSingletonNameIn ) :
strSingletonName( strSingletonNameIn ),
isConstructed( false ) {}
};
// Order Must Match Types Defined In Singleton::SingletonType enum
static std::array<SingletonInfo, 1> s_aSingletons = { SingletonInfo( "Logger" ) }; /*,
SingletonInfo( "Settings" ) };*/ // Make Sure The Number Of Types Matches The Number In This Array
Singleton::Singleton( SingletonType eType ) :
m_eType( eType ) {
bool bSaveInLog = s_aSingletons.at( TYPE_LOGGER ).isConstructed;
try {
if ( !s_aSingletons.at( eType ).isConstructed ) {
// Test Initialization Order
for ( int i = 0; i < eType; ++i ) {
if ( !s_aSingletons.at( i ).isConstructed ) {
throw ExceptionHandler( s_aSingletons.at( i ).strSingletonName + " must be constructed before constructing " + s_aSingletons.at( eType ).strSingletonName, bSaveInLog );
}
}
s_aSingletons.at( eType ).isConstructed = true;
/*if ( s_aSingletons.at( TYPE_ENGINE ).isConstructed &&
Setttings::get()->isDebugLogginEnabled( Settings::DEBUG_MEMORY ) ) {
logMemoryAllocation( true );
}*/
} else {
throw ExceptionHandler( s_aSingletons.at( eType ).strSingletonName + " can only be constructed once.", bSaveInLog );
}
} catch ( std::exception& ) {
// eType Is Out Of Range
std::ostringstream strStream;
strStream << __FUNCTION__ << " Invalid Singleton Type Specified: " << eType;
throw ExceptionHandler( strStream, bSaveInLog );
}
}
Singleton::~Singleton() {
/*if ( s_aSingletons.at( TYPE_ENGINE ).isConstructed &&
Settings::get()->isDebugLoggingEnabled( Settings::DEBUG_MEMORY ) ) {
logMemoryAllocation( false );
}*/
s_aSingletons.at( m_eType ).isConstructed = false;
}
void Singleton::logMemoryAllocation( bool isAllocated ) const {
if ( isAllocated ) {
Logger::log( "Created " + s_aSingletons.at( m_eType ).strSingletonName );
} else {
Logger::log( "Destroyed " + s_aSingletons.at( m_eType ).strSingletonName );
}
}
} // namespace pro
<强> Logger.h 强>
#ifndef LOGGER_H
#define LOGGER_H
#include "Singleton.h"
namespace pro {
class Logger sealed : public Singleton {
public:
// Number Of Items In Enum Type Must Match The Number
// Of Items And Order Of Items Stored In s_aLogTypes
enum LoggerType {
TYPE_INFO = 0,
TYPE_WARNING,
TYPE_ERROR,
TYPE_CONSOLE,
}; // LoggerType
private:
std::string m_strLogFilename;
unsigned m_uMaxCharacterLength;
std::array<std::string, 4> m_aLogTypes
const std::string m_strUnknownLogType;
HANDLE m_hConsoleOutput;
WORD m_consoleDefualtColor;
public:
explicit Logger( const std::string& strLogFilename );
virtual ~Logger();
static void log( const std::string& strText, LoggerType eLogType = TYPE_INFO );
static void log( const std::ostringstream& strStreamText, LoggerType eLogType = TYPE_INFO );
static void log( const char* szText, LoggerType eLogType = TYPE_INFO );
private:
Logger( const Logger& c ); // Not Implemented
Logger& operator=( const Logger& c ); // Not Implemented
}; // Logger
} // namespace pro
#endif // LOGGER_H
<强> Logger.cpp 强>
#include "stdafx.h"
#include "Logger.h"
#include "BlockThread.h"
#include "TextFileWriter.h"
namespace pro {
static Logger* s_pLogger = nullptr;
static CRITICAL_SECTION = s_criticalSection;
// White Text On Red Background
static const WORD WHITE_ON_RED = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED;
Logger::Logger( const std::string& strLogFilename ) :
Singleton( TYPE_LOGGER ),
m_strLogFilename( strLogFilename ),
m_uMaxCharacterLength( 0 ),
m_strUnknownLogType( "UNKNOWN" ) {
// Order Must Match Types Defined In Logger::Type enum
m_aLogTypes[0] = "Info";
m_aLogTypes[1] = "Warning";
m_aLogTypes[2] = "Error";
m_aLogTypes[3] = ""; // Console
// Find Widest Log Type String
m_uMaxCharacterLength = m_strUnknownLogType.size();
for each( const std::string& strLogType in m_aLogTypes ) {
if ( m_uMaxCharacterLength < strLogType.size() ) {
m_uMaxCharacterLength = strLogType.size();
}
}
InitializeCriticalSection( &s_criticalSection );
BlockThread blockThread( s_criticalSection ); // Enter Critical Section
// Start Log File
TextFileWriter file( m_strLogFilename, false, false );
// Prepare Console
m_hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
CONSOLE_SCREEN_BUFFER consoleInfo;
GetConsoleScreenBufferInfo( m_hConsoleOutput, &consoleInfo );
m_consoleDefaultColor = consoleInfo.wAttributes;
s_pLogger = this;
logMemoryAllocation( true );
}
Logger::~Logger() {
logMemoryAllocation( false );
s_pLogger = nullptr;
DeleteCriticalSection( &s_criticalSection );
}
void Logger::log( const std::string& strtext, LoggerType eLogType ) {
log( strText.c_str(), eLogType );
}
void Logger::log( const std::string& strText, LoggerType eLogType ) {
log( strText.str().c_str(), eLogType );
}
void Logger::log( const char* szText, LoggerType eLogType ) {
if ( nullptr == s_pLogger ) {
std::cout << "Logger has not been initialized, can not log " << szText << std::endl;
return;
}
BlockThread blockThread( s_criticalSection ); // Enter Critical Section
std::ostringstream strStream;
// Default White Text On Red Background
WORD textColor = WHITE_ON_RED;
// Chose Log Type Text String, Display "UNKNOWN" If eLogType Is Out Of Range
strStream << std::setfill(' ') << std::setw( s_pLogger->m_uMaxCharacterLength );
try {
if ( TYPE_CONSOLE != eLogType ) {
strStream << s_pLogger->m_aLogTypes.at( eLogType );
}
if ( TYPE_WARNING == eLogType ) {
// Yellow
textColor = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN;
} else if ( TYPE_INFO == eLogType ) {
// Green
textColor = FOREGROUND_GREEN;
} else if ( TYPE_CONSOLE == eLogType ) {
// Cyan
textColor = FOREGROUND_GREEN | FOREGROUND_BLUE;
}
} catch( ... ) {
strStream << s_pLogger->m_strUnknownLogType;
}
// Date And Time
if ( TYPE_CONSOLE != eLogType ) {
SYSTEMTIME time;
GetLocalTime( &time );
strStream << " [" << time.wYear << "."
<< std::setfill('0') << std::setw( 2 ) << time.wMonth << "."
<< std::setfill('0') << std::setw( 2 ) << time.wDay << " "
<< std::setfill(' ') << std::setw( 2 ) << time.wHour << ":"
<< std::setfill('0') << std::setw( 2 ) << time.wMinute << ":"
<< std::setfill('0') << std::setw( 2 ) << time.wSecond << "."
<< std::setfill('0') << std::setw( 3 ) << time.wMilliseconds << "] ";
}
strStream << szText << std::endl;
// Log Message
SetConsoleTextAttribute( s_pLogger->m_hConsoleOutput, textColor );
std::cout << strStream.str();
// Save Message To Log File
try {
TextFileWriter file( s_pLogger->m_strLogFilename, true, false );
file.write( strStream.str() );
} catch( ... ) {
// Not Saved In Log File, Write Message To Console
std::cout << __FUNCTION__ << " failed to write to file: " << strStream.str() << std::endl;
}
// Reset To Default Color
SetConsoleTextAttribute( s_pLogger->m_hConsoleOutput, s_pLogger->m_consoleDefaultColor );
}
} // namespace pro
FileHandler.h - 基类
#ifndef FILE_HANDLER_H
#define FILE_HANDLER_H
namespace pro {
// class AssetStorage; // Not Used Here
class FileHandler {
protected:
// static AssetStorage* m_pAssetStorage; // Not Used Here
std::fstream m_fileStream;
std::string m_strFilePath;
std::string m_strFilenameWithPath;
private:
bool m_bSaveExceptionInLog;
public:
virtual ~FileHandle();
protected:
FileHandler( const std::string& strFilename, bool bSaveExceptionInLog );
void throwError( const std::string& strMessage ) const;
void throwError( const std::ostringstream& strStreamMessage ) const;
bool getString( std::string& str, bool appendPath );
private:
FileHandler( const FileHandler& c ); // Not Implemented
FileHandler& operator=( const FileHandler& c ); // Not Implemented
}; // FileHandler
} // namespace pro
#endif // FILE_HANDLER_H
<强> FileHandler.cpp 强>
#include "stdafx.h"
#include "FileHandler.h"
// #include "AssetStorage.h" // Not Used Here
namespace pro {
// AssetStorage* FileHandler::m_pAssetStorage = nullptr; // Not Used Here
FileHandler::FileHandler( const std::string& strFilename, bool bSaveExceptionInLog ) :
m_bSaveExceptionInLog( bSaveExceptionInLog ),
m_strFilenameWithPath( strFilename ) {
/*if ( bSaveExceptionInLog && nullptr == m_pAssetStorage ) {
m_pAssetStorage = AssetStorage::get();
}*/ // Not Used Here
// Extract Path Info If It Exists
std::string::size_type lastIndex = strFilename.find_last_of( "/\\" );
if ( lastIndex != std::string::npos ) {
m_strFilePath = strFilename.substr( 0, lastIndex );
}
if ( strFilename.empty() ) {
throw ExceptionHandler( __FUNCTION__ + std::string( " missing filename", m_bSaveExceptionInLog );
}
}
FileHandler::~FileHandler() {
if ( m_fileStream.is_open() ) {
m_fileStream.close();
}
}
void FileHandler::throwError( const std::string& strMessage ) const {
throw ExceptionHandler( "File [" + m_strFilenameWithPath + "] " + strMessage, m_bSaveExceptionInLog );
}
void FileHandler::throwError( const std::ostringstream& strStreamMessage ) const {
throwError( strStreamMessage.str() );
}
bool FileHandler::getString( std::string& str, bool appendPath ) {
m_fileStream.read( &str[0], str.size() );
if ( m_fileStream.fail() ) {
return false;
}
// Trim Right
str.erase( str.find_first_of( char( 0 ) ) );
if ( appendPath && !m_strFilePath.empty() ) {
// Add Path If One Exists
str = m_strFilePath + "/" + str;
}
return true;
}
} // namespace pro
现在您正在等待处理文件流的两个继承类。这两个是严格文本。我的项目中的其他人是TextureFiles,ModelObjectFiles等。我将只显示TextFileReader&amp; TextFileWriter。
<强> TextFileReader.h 强>
#ifndef TEXT_FILE_READER_H
#define TEXT_FILE_READER_H
#include "FileHandler.h"
namespace pro {
class TextFileReader : public FileHandler {
private:
public:
explicit TextFileReader( const std::string& strFilename );
// virtual ~ TextFileReader(); // Default Okay
std::string readAll() const;
bool readLine( std::string& strLine );
private:
TextFileReader( const TextFileReader& c ); // Not Implemented
TextFileReader& operator=( const TextFileReader& c ); // Not Implemented
}; // TextFileReader
} // namespace pro
#endif // TEXT_FILE_READER_H
<强> TextFileReader.cpp 强>
#include "stdafx.h"
#include "TextFileReader.h"
namespace pro {
TextFileReader::TextFileReader( const std::string& strFilename ) :
FileHandler( strFilename, true ) {
m_fileStream.open( m_strFilenameWithPath.c_str(), std::ios_base::in );
if ( !m_fileStream.is_open() ) {
throwError( __FUNCTION__ + std::string( " can not open file for reading" ) );
}
std::string TextFileReader::readAll() const {
std::ostringstream strStream;
strStream << m_fileStream.rdbuf();
return strStream.str();
}
bool TextFileReader::readLine( std::string& strLine ) {
if ( m_fileStream.eof() ) {
return false;
}
std::getline( m_fileStream, strLine );
return true;
}
} // namespace pro
<强> TextFileWriter.h 强>
#ifndef TEXT_FILE_WRITER_H
#define TEXT_FILE_WRITER_H
#include "FileHandler.h"
namespace pro {
class TextFileWriter : public FileHandler {
private:
public:
TextFileWriter( const std::string& strFilename, bool bAppendToFile, bool bSaveExceptionInLog = true );
void write( const std::string& str );
private:
TextFileWriter( const TextFileWriter& c ); // Not Implemented
TextFileWriter& operator=( const TextFileWriter& c ); // Not Implemented
}; // TextFileWriter
} // namespace pro
#endif // TEXT_FILE_WRITER_H
<强> TextFileWriter.cpp 强>
#include "stdafx.h"
#include "TextFileWriter.h"
namespace pro {
TextFileWriter::TextFileWriter( const std::string& strFilename, bool bAppendToFile, bool bSaveExceptionInLog ) :
FileHandler( strFilename, bSaveExceptionInLog ) {
m_fileStream.open( m_strFilenameWithPath.c_str(),
std::ios_base::out | ( bAppendToFile ? std::ios_base::app : std::ios_base::trunc ) );
if ( !m_fileStream.is_open() ) {
throwError( __FUNCTION__ + std::string( " can not open file for writing" ) );
}
}
void TextFileWriter::write( const std::string& str ) {
m_fileStream << str;
}
} // namespace pro
现在看一下这个实例的样本。如果查看Logger
类,您将看到TextFileWriter的使用。
<强>的main.cpp 强>
#include "stdafx.h"
#include "Logger.h"
#include "TextFileReader.h"
#include "TextFileWriter.h"
int _tmain( int iNumArguments, _TCHAR* pArgumentText[] ) {
using namespace pro;
try {
// This Is Using The TextFileWriter & Console Output
// Logger::TYPE_INFO is by default!
Logger logger( "logger.txt" );
logger.log( "Some Info" );
logger.log( "Error!", Logger::TYPE_ERROR );
logger.log( "Warning!", Logger::TYPE_WARNING );
TextFileReader textReaderSingle( "logger.txt" );
TextFileReader textReaderAll( "logger.txt" );
std::string strTextSingle;
std::string strTextAll;
textReaderSingle.readLine( strTextSingle );
std::cout << "Read Single Line: << std::endl << strText << std::endl << std::endl;
strTextAll = textReaderAll.readAll();
std::cout << "Read All: " << std::endl << strTextAll << std::endl;
//Check The logger.txt that was generated in your projects folder!
std::cout << "Press any key to quit" << std::endl;
_getch();
} catch ( ExceptionHandler& e ) {
std::cout << "Exception Thrown: " << e.getMessage() << std::endl;
std::cout << "Press any key to quit" << std::endl;
_getch();
return RETURN_ERROR;
} catch( ... ) {
std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
std::cout << "Press any key to quit" << std::endl;
_getch();
return RETURN_ERROR;
}
return RETURN_OK;
}
这项工作的大部分是由www.MarekKnows.com的MASc的Marek A. Krzeminski认可的。实质上所有这些类对象都是他的;唯一的主要区别是我使用自己的namespace pro
而不是他的。两个main
函数都是我自己的工作,第一个独立,第二个使用他的库代码。
这个项目已经开展了几年,我对C ++语言的大部分高级知识都是遵循他的视频教程。这个当前项目是一个相当大规模的专业品质GameEngine,使用OpenGL中的Shaders。所有这些都是在他的教程之后手动打字和调试的。
作为主要说明;我也曾在这里输入大部分内容,如果这不能正确编译,可能是由于印刷错误。它自己的源是一个工作的应用程序。你在这里看到的只是他作品的一小部分!我愿意接受这个问题,因为这些知识的积累可以回答这个人的问题,但我不能否认这是为了保护马立克及其版权材料而成为我自己的工作。
通过这种设置,可以很容易地为不同类型的文件创建自己的文件解析器和多个文件解析器。正如我上面所说,还有另外两个继承自FileHandler
的类,我没有展示。如果您想了解更多此项目,请访问www.MarekKnows.com并加入社区。 p>