2016-03-25 2 views
0

мой проект, над которым я работаю над сделками с пользователем, вводящим число, а затем получая случайные числа для циклического вывода в файл под названием «Numbers.txt».C++ Может ли fstream infile использоваться для сбора данных из недавно использованного outstream-файла?

int number = 0; 
cout << "enter a number: << endl; 
cin >> number; 
ofstream outfile; 
string Filename; 
Filename = "Numbers.txt"; 
outfile.open(Filename); 
if (outfile) 
{ 
    for (int i = 0; i < number; i++) 
    { 
    outfile << rand() % 100 << endl; 
    } 
} 
outfile.close(); 

Теперь после того, как выходной_файл данные обрабатываются, я хочу взять в этих данных обратно снова, используя переменный fstream под названием входной_файл. Возможна ли операция, подобная приведенной ниже, после завершения outfile? Моя главная цель - прочитать в том, что было случайно выпущено в файл, чтобы в конечном итоге я смог обработать его в связанном списке. Я проверил код, подобный этому, но в результате я получаю нули. Благодарю.

ifstream infile; 
    string FileName = "Numbers.txt"; 
    infile.open(FileName); 
    while (infile) 
    { 
     infile >> RandomNumber; 
     cout << RandomNumber << endl; 
    } 
    infile.close(); 
+0

Почему вы думаете, что это может быть невозможно? –

+0

, потому что я протестировал код, почти похожий на этот .. и когда я это сделал. Я получил нули – Nathan

+1

Проверьте файл, чтобы увидеть, есть ли какие-либо '0' s. Если это так, это не код ввода, который закручивается, это код вывода. Кроме того, убедитесь, что вы устанавливаете 'rand' вправо, используя' srand() '. –

ответ

1

Это должно работать if (infile) будет проверять, если файл открыт и while (infile >> RandomNumber) получите все номера в файле:

ifstream infile; 
string FileName = "Numbers.txt"; 
infile.open(FileName); 
if (infile) { 
    while (infile >> RandomNumber) { 
     cout << RandomNumber << endl; 
    } 
} 
infile.close(); 
+0

И с этого момента вы можете в принципе помещать эти данные в любом месте, как связанный список, массив и т. д.? – Nathan

+0

Да, вы можете поместить данные в любом месте. – DimChtz

+0

Оператор if не нужен. В то время уже будет выполнено это, если. См. Мой комментарий к основному вопросу. – user2913685

0
int number = 0; 
string filename("Numbers.txt"); 
std::ofstream out; 
std::ifstream in; 

std::cout << "enter a number: << std::endl; 
std::cin >> number; 

out.open(filename.c_str(), std::ios_base::out); 
if (!out.is_open()){ 
    // Print, Log Error, Throw Error, Return Etc. 
} 

for (int i = 0; i < number; i++) { 
    out << rand() % 100 << std::endl; 
} 
out.close(); 

in.open(filename.c_str(), std::ios_base::in); 
if (!in.is_open()) { 
    // Error Case Here 
} 

while (!in.eof()) { // Usually bad practice; but my file handling classes are parser objects are too large to show here. 
    in >> RandomNumber; 
    std::cout << RandomNumber << endl; 
} 
infile.close(); 
0

Это не является ответом на ППО вопрос, а скорее он предоставляется для небольшого разговора в серии комментариев о чтении файлов и анализе данных. Это направлено на Тони и всех, кто хотел бы использовать эту установку класса. В этом классе есть некоторые вещи, которые относятся к другим классам в моей библиотеке, некоторые из которых включают в себя мой Logger, который будет регистрировать сообщения либо в файле, либо в консоли, а типы сообщений - это Info, Warning, Error или Console. Мой регистратор получен из класса Singleton, так как для обработки всех сообщений мне понадобится только один регистратор на одно решение. У меня есть класс Utility, который обрабатывает большинство функций манипуляции строками, где конструктор является закрытым, а все функции или члены объявляются как статические. Этот класс также полагается на класс ExceptionHandler, который будет принимать объекты std :: strings или std :: ostringstream. Мой Logger принимает то же самое. Кроме того, некоторые из моих классов также полагаются на класс BlockThread, который позволяет работать с многопоточным процессом, который после построения будет создавать и инициализировать CriticalSection, а затем вводить критический раздел, а затем после уничтожения он уйдет, а затем уничтожит CriticalSection. Теперь, что касается этой демонстрации, я буду показывать только классы FileHandler вместе с двумя ее производными типами TextFileReader и TextFileWriter. У меня есть более производные FileHandlers, которые работают с чтением в файлах текстур, настраиваемых структур данных и т. Д., Которые работают с двоичными файлами, а не с текстовым файлом, но для этого будут показаны только обработчики текстовых файлов.

FileHandler.h

#ifndef FILE_HANDLER_H 
#define FILE_HANDLER_H 

namespace util { 

//class AssetStorage; 

class FileHandler { 
protected: 
    //static AssetStorage* m_pAssetStorage; 

    std::fstream m_fileStream; 
    std::string  m_strFilePath; 
    std::string  m_strFilenameWithPath; 

private: 
    bool m_bSaveExceptionInLog; 

public: 
    virtual ~FileHandler(); 

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 util 

FileHandler.cpp

#include "stdafx.h" 
#include "FileHandler.h" 

namespace util { 

// ---------------------------------------------------------------------------- 
// FileHandler() 
FileHandler::FileHandler(const std::string& strFilename, bool bSaveExceptionInLog) : 
m_bSaveExceptionInLog(bSaveExceptionInLog), 
m_strFilenameWithPath(strFilename) { 

    // 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 
FileHandler::~FileHandler() { 
    if (m_fileStream.is_open()) { 
     m_fileStream.close(); 
    } 
} // ~FileHandler 

// ---------------------------------------------------------------------------- 
// throwError() 
void FileHandler::throwError(const std::string& strMessage) const { 
    throw ExceptionHandler("File [" + m_strFilenameWithPath + "] " + strMessage, m_bSaveExceptionInLog); 
} // throwError(const std::string) 

// ---------------------------------------------------------------------------- 
// throwError() 
void FileHandler::throwError(const std::ostringstream& strStreamMessage) const { 
    throwError(strStreamMessage.str()); 
} // throwError(const std::ostringstream) 

// ---------------------------------------------------------------------------- 
// getString() 
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 Exixsts 
     str = m_strFilePath + "/" + str; 
    } 

    return true; 
} // getString 

} // namespace util 

TextFileReader.h

#ifndef TEXT_FILE_READER_H 
#define TEXT_FILE_READER_H 

#include "FileHandler.h" 

namespace util { 

class TextFileReader : public FileHandler { 
private: 

public: 
    explicit TextFileReader(const std::string& strFilename); 
    // virtual ~TextFileReader(); // Default OK 

    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 util 

#endif // TEXT_FILE_READER_H 

TextFileReader.cpp

#include "stdafx.h" 
#include "TextFileReader.h" 

namespace util { 

// ---------------------------------------------------------------------------- 
// TextFileReader() 
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")); 
    } 
} // TextFileReader 

// ---------------------------------------------------------------------------- 
// readAll() 
std::string TextFileReader::readAll() const { 
    std::ostringstream strStream; 
    strStream << m_fileStream.rdbuf(); 

    return strStream.str(); 
} // readAll 

// ---------------------------------------------------------------------------- 
// readLine() 
// Returns A String Containing The Next Line Of Text Stored In The File 
bool TextFileReader::readLine(std::string& strLine) { 
    if (m_fileStream.eof()) { 
     return false; 
    } 
    std::getline(m_fileStream, strLine); 
    return true; 
} // readLine 

} // namespace util 

TextFileWriter.h

#ifndef TEXT_FILE_WRITER_H 
#define TEXT_FILE_WRITER_H 

#include "FileHandler.h" 

namespace util { 

class TextFileWriter : public FileHandler { 
private: 

public: 
    TextFileWriter(const std::string& strFilename, bool bAppendToFile, bool bSaveExceptionInLog = true); 
    // virtual ~TextFileWriter(); // Default OK 

    void write(const std::string& str); 

private: 
    TextFileWriter(const TextFileWriter& c); // Not Implemented 
    TextFileWriter& operator=(const TextFileWriter& c); // Not Implemented 

}; // TextFileWriter 

} // namespace util 

#endif // TextFileWriter 

TextFileWriter.каст

#include "stdafx.h" 
#include "TextFileWriter.h" 

namespace util { 

// ---------------------------------------------------------------------------- 
// TextFileWriter() 
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")); 
    } 
} // TextFileWriter 

// ---------------------------------------------------------------------------- 
// write() 
void TextFileWriter::write(const std::string& str) { 
    m_fileStream << str; 
} // write 

} // namespace util 

А вот некоторые фрагменты кода из класса, который используется в FileHandlers.

Это заголовок класса, в котором используется FileHandler. Он читает в текстовом файле и анализирует его, чтобы определить, какие объекты GUI создавать, загружать в память и как они должны отображаться на экране, а также накладывать один GUI типа в качестве ребенка другому. Я не буду показывать полную реализацию этого класса, но только несколько функций, где это касается использования FileHandlers.

GuiLoader.h

#ifndef GUI_LOADER_H 
#define GUI_LOADER_H 

#include "Engine.h" 

#include "CommonStructs.h" 
#include "Property.h" 
#include "TextFileReader.h" 

namespace vmk { 

class AssetStorage; 

class GuiCompositeElement; 
class GuiElement; 
class GuiLayout; 
class GuiRenderable; 
class GuiText; 

class VisualMko; 

class GuiLoader sealed { 
    friend GuiElement* Engine::loadGui(const std::string& strFilename) const; 
private: 
    std::string  m_strFilename; 
    util::TextFileReader m_file; 

    bool  m_inBlockComment; 
    unsigned m_uNumBracesOpened; 
    unsigned m_uLineNumber; // Keep Track OfLine Number For Error Messages 

    GuiElement* m_pLastGuiRoot; 
    std::vector<GuiCompositeElement*> m_vpParents; 

    std::string m_strLine; 

    std::unordered_map<std::string, TextureInfo> m_mTextureInfos; 
    std::unordered_map<std::string, FontFace> m_mFontFace; 

    FontManager* m_pFontManager; 
    AssetStorage* m_pAssetStorage; 

public: 
    // virtual ~GuiLoader(); // Default Ok 

    GuiElement* getRoot() const; 

private: 
    GuiLoader(const std::string& strFilename); 

    GuiLoader(const GuiLoader& c); // Not Implemented 
    GuiLoader& operator=(const GuiLoader& c); // Not Implemented 

    bool getNextLine(); 
    std::string getFailedLocation() const; 
    void removeComments(); 
    void parseGui(); 
    bool handleOpenBrace(unsigned uStartLocation, GuiCompositeElement* pGui); 
    void addToParent(GuiRenderable* pRenderable) const; 

    bool getParameter(std::string strParam, unsigned uStartLocation, std::string& strValue, bool isRequired = true, char endCharacter = ' ') const; 
    void setOptionalParameters(unsigned uStartLocation, GuiElement* pGui) const; 
    void getOptionalLayoutParameters(unsigned uStartLocation, glm::ivec2& offsetFromParent, Gui::Alignment& eAlignChildren, glm::uvec2& size, std::string& strId) const; 
    void setLayoutParameters(unsigned uStartLocation, GuiLayout* pLayout) const; 
    bool getOptionalBackgroundParameters(unsigned uStartLocation, TextureInfo& textureInfo, glm::uvec2& origin) const; 
    bool getOptionalBackgroundParameters(unsigned uStartLocation, TextureInfo& textureInfo, glm::uvec2& origin, glm::uvec2& size, bool isRequired = true) const; 
    void getRequiredTextParameters(unsigned uStartLocation, FontFace& fontFace, std::string& strText) const; 

    void setTextShadowParameters(unsigned uStartLocation, GuiText* pGui) const; 

    void setVisualMkoParameters(unsigned uStartLocation, VisualMko* pVisualMko) const; 

}; // GuiLoader 

} // namespace vmk 

#endif // GUI_LOADER_H 

GuiLoader.cpp - только несколько участков показаны

#include "stdafx.h" 
#include "GuiLoader.h" 

#include "AssetStorage.h" 
#include "FontManager.h" 
#include "Gui.h" 
#include "Image2d.h" 
#include "Logger.h" 
#include "TextureFileReader.h" 
#include "Utility.h" 

using namespace util; 

namespace vmk { 

// ---------------------------------------------------------------------------- 
// GuiLoader() 
GuiLoader::GuiLoader(const std::string& strFilename) : 
m_strFilename(strFilename), 
m_file(strFilename), 
m_inBlockComment(false), 
m_uNumBracesOpened(0), 
m_uLineNumber(0), 
m_pLastGuiRoot(nullptr), 
m_pFontManager(FontManager::get()), 
m_pAssetStorage(AssetStorage::get()) { 
    while (getNextLine()) { 
     parseGui(); 
    } 

    if (m_uNumBracesOpened > 0) { 
     std::ostringstream strStream; 
     strStream << __FUNCTION__ << getFailedLocation() << ". Missing " << m_uNumBracesOpened << " closing brace" << (m_uNumBracesOpened > 1 ? "s" : "") << "."; 
     throw ExceptionHandler(strStream); 
    } 

    if (m_inBlockComment) { 
     std::ostringstream strStream; 
     strStream << __FUNCTION__ << getFailedLocation() << ". Missing closing block comment */."; 
    } 
} // GuiLoader 

// ---------------------------------------------------------------------------- 
// getRoot() 
GuiElement* GuiLoader::getRoot() const { 
    return m_pLastGuiRoot; 
} // getRoot 

// ---------------------------------------------------------------------------- 
// getNextLine() 
// Returns True If Got A Line Of Text (Could Be Blank If It Is All Commented 
// Out Or If It Truly Was A Blank Line). False is Returned When There Is 
// No More Data In The File 
bool GuiLoader::getNextLine() { 
    if (!m_file.readLine(m_strLine)) { 
     return false; 
    } 

    ++m_uLineNumber; 

    m_strLine = Utility::trim(m_strLine); 
    //std::cout << m_uLineNumber << ": " << m_strLine << std::endl; // Use This For Debugging The GuiLoader 

    removeComments(); 

    return true; 
} // getNextLine 

// ... Other Functions Here 

} // namespace vmk 

Это было представлено, чтобы показать надежность моих классов обработки файлов. Здесь не так много других классов. Моя библиотека является частью библиотеки 3D-рендеринга, которая использует Modern OpenGL. Существует несколько сотен объектов класса и 100 000 строк кода для выполнения 3D-рендеринга, загрузки спрайтов, моделирования физики, анимации, воспроизведения звука, воспроизведения аудиопотока и многое другое. Не весь этот исходный код имеет мою собственную конструкцию, поэтому этот код защищен Marek A. Krzeminski, MASc, а его работы можно найти по адресу: www.MarekKnows.com

Весь код, показанный здесь, не был скопирован и вставлен с его сайта, все это было напечатано вручную, а затем сопровождалось его видеоуроками. Он был скомпилирован и отлажен вручную. Этот проект работает в течение нескольких лет, и до сих пор добавляется еще больше. Я с гордостью отношусь к его веб-сайту и сообществу с 2007 по 2008 год.

+0

Привет, Фрэнсис. Это много кода! Он не показывает отличного понимания обернутых функций стандартной библиотеки C++, например. - Деструктору 'FilterHandler' никогда не нужно вызывать' m_fileStream.close(); ', поскольку дескриптор потока обрабатывает это внутренне. 'TextFileReader :: readLine' имеет точный баг, который я описал вам с помощью EOF-обработки, а' ':: readAll' включает строчную копию всего содержимого файла, которое не будет оптимизировано. –

Смежные вопросы