2015-10-20 42 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並加入社區。

相關問題