2015-10-20 34 views
0

如何在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行,现在我想忽略在第5上述4线和输入单词“输入” (在“学生”一词下面)。当我运行上面的代码时,输​​出文件是空白的。任何建议如何解决这个问题?谢谢。

+0

什么不符合你的代码? – 0x499602D2

+0

我的输出文件(2.txt)是空白的。 – Marco

+0

为什么不尝试调试程序?逐行浏览并观察会发生什么。 – crashmstr

回答

1

当你正在阅读的5日线,lineNumber等于4 B/C你0 变化if(lineNumber == 5)if(lineNumber == 4)你也有你在哪里设置lineNumber = 0然后立即递增到1的问题,开始你的票,所以你只需要再次输出4行。

+0

输出文件仍为空白。 – Marco

+0

如果你没有得到任何输出,那么你的1.txt文件中没有任何内容,或者你的'getline'声明无论如何都无法正常工作。 – TriHard8

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 

ps要学习和了解编程更好,我会建议不要使用:

using namespace std; 
+1

你显然没有测试这个。 – TriHard8

+0

我做了..这似乎有点粗鲁..什么部分不编译和工作..? – badola

+0

哦,对,@ TriHard8 ...我现在明白了。 我纠正了我的错误。感谢您指出。 :) – badola

1

我将创建一个这样的功能...

bool isBlank(string line) { 
    if (!line.empty()) { 
     for (auto x: line) { 
      if (isalnum(x)) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

如果字符串为空或没有字母,则返回true字符。

您可以在getline语句后立即调用此函数。

字符isalnum功能在<cctype>

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号线的话学生就是你必须在该文本文件中后至少有2个空行。一个简单的输入或回车将做到!如果你不while(getline())将超出范围,它不会读取下一行,并且当lineNumber == 5时代码块将永远不会输入您的if()语句,并且它不会将文本"Input"打印到您的stream2文件流对象。

如果你在你的1.txt文件文本的最后一行是有文字Student的串这里发生的事情是它这行文字添加到您的line字符串变量,则代码将增加你的lineNumber等于5行。下一次进入while循环调用getline()时,它将返回false,因为您位于EOF,因为文件中没有更多文本要读入,这会导致while循环跳出执行,并且它会熄灭范围和if(lineNumber == 5)永远不会被调用,因为它嵌套在while循环的范围内。

1

我的第一个答案解决了您的问题的问题,并适当地获得输出到您的文本文件。然而,正如我所提到的关于阅读一行文本的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,Op​​enAL的,奥格 - 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 

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 

LoggerSingleton因为在应用程序运行时您只需要它的一个实例。

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 & 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; 
} 

大部分这项工作是认可的马立克A.克热明斯基,睫毛膏在www.MarekKnows.com。实质上所有这些类对象都是他的;唯一的主要区别是我用我自己的namespace pro而不是他的。 main这两个函数都是我自己的工作,第一个单独使用,第二个使用他的库代码。

这是一个已经工作了几年的项目,我对C++语言的大部分高级知识都是由于他的视频教程。这个当前的项目是一个在OpenGL中使用着色器的相当大规模的专业质量的GameEngine。所有这些都是按照他的教程进行输入和调试的。

作为一个主要说明;我也在这里输入了大部分内容,如果编译不正确,可能是由于印刷错误。它自己的源代码是一个可用的应用程序。你在这里看到的是他作品中的一小部分!我愿意接受这个信誉,以积累这些知识来回答这个人的问题,但我不能接受这个信誉作为我自己的工作,以保护马立克和他的版权资料。

通过这种设置,可以非常容易地为不同类型的文件创建自己的文件分析器和多个文件分析器。正如我上面所述,还有两个其他类从FileHandler继承,我没有显示。如果您希望看到更多这个项目,请访问www.MarekKnows.com并加入社区。

相关问题