如何在写入文件时忽略行
how to ignore lines when writing to a file
如何在 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;
}
在"1.txt"中,我在第 4 行有"学生"一词,现在我想忽略上述 4 行,并在第 5 行(在"学生"一词下方(输入"输入"一词。当我运行上面的代码时,输出文件为空。任何建议如何解决这个问题?谢谢。
理解正确,您想要的只是 1.txt in 2.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自卫数据局.sdfg三1464BFGNDTY45y564格特格
输出文件 (2.txt( -
SDLFKNAS自卫数据局.sdfg输入1464BFGNDTY45y564格特格
附言为了更好地学习和理解编程,我建议不要使用:
using namespace std;
当你阅读第 5 行时,lineNumber
等于 4 b/c,你从 0 开始计数。更改if(lineNumber == 5)
到 if(lineNumber == 4)
您还有一个问题,即您设置lineNumber = 0
然后立即递增到 1,因此您只需要数 4 行,然后再次输出。
我会创建一个这样的函数...
bool isBlank(string line) {
if (!line.empty()) {
for (auto x: line) {
if (isalnum(x)) {
return false;
}
}
}
return true;
}
如果字符串为空或没有字母数字字符,则返回 true。
您可以在 getline 语句之后立即调用此函数。
isalnum 函数在 <cctype>
中指定
使用您的代码后,我设法获得了您想要的输出。下面是代码的更新版本。
#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() )
将超出范围,它不会读取下一行,并且代码块在lineNumber == 5
时永远不会输入您的if()
语句,并且不会将文本"Input"
打印到您的stream2
文件流对象。
如果1.txt
文件中的最后一行文本是带有文本字符串的行Student
这里发生的情况是它会将此行文本添加到您的line
字符串变量中,然后代码将增加您的lineNumber
以等于5
。下次进入 while 循环调用getline()
时,它会返回 false,因为您处于EOF
,因为文件中没有更多的文本行可供读取,这会导致 while 循环中断执行并超出范围,并且永远不会调用if( lineNumber == 5 )
,因为它嵌套在while
循环的作用域内。
我的第一个答案解决了您的问题,并适当地将输出到您的文本文件中。但是,正如我提到的,用于读取一行文本并对两个文件流使用相同的计数器的 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 注意:并非所有这些包含和定义都将在这里使用,但这来自我的一个更大的项目,我只删除了这里需要的类,但保留我的标准标头。我从这个"stdafx.h"中删除的唯一内容是任何必须处理OpenGL,OpenAL,Ogg - Vorbis,GLM库和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
异常处理程序.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
块线程.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
,因为在应用程序运行时,您只需要它的一个实例。
辛格尔顿
#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
辛格尔顿.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
记录器.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
记录器.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
文件处理程序.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和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
文本文件读取器.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
文本文件编写器.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的使用。
主.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++语言的大部分高级知识都是由于遵循他的视频教程。目前的这个项目是一个相当大规模的专业质量游戏引擎,使用OpenGL中的着色器。所有这些都是在按照他的教程进行操作时手动键入和调试的。
作为主要说明;我也在这里手工输入了大部分内容,如果这不能正确编译,可能是由于印刷错误。它本身的源是一个工作应用程序。你在这里看到的只是他作品的一小部分!我愿意接受用这些知识的积累来回答这个人的问题的功劳,但我不能接受这是我自己的作品,以保护马雷克和他的版权材料。
通过这种设置,很容易为不同类型的文件创建自己的文件解析器和多个文件解析器。正如我上面所说,还有另外两个从FileHandler
继承的类我没有展示。如果您想看到更多这个项目,请访问 www.MarekKnows.com 并加入社区。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到