#include <string> #include <fstream> typedef std::vector<std::vector<std::string>> StringListArray; //In some header someplace //================================================== //From another file: //Writes the string out as a file. Returns false if it fails. bool SaveStringAsFile(const std::string &filename, const std::string &data) { //Open the file for writing. std::ofstream file(filename.c_str(), std::ios_base::out | std::ios_base::trunc); if(!file) { Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename) << " for writing.\nDo I have sufficient privileges? Does the path exist? Is that file already in use?" << Log::FlushStream; return false; } //Write the entire datastring to the file. file << data; return true; } //================================================== //From another file: /* Loads a CSV (Comma-seperated-value) file and returns the result as a vector of each line of the file. Each StringList in the vector is a file line, and each string in the StringList is one of the parameters of that line. Extra whitespace around commas are removed. When loading, if 'keepRowsSameSize' is true, ensures that every row has the same number of columns, by appending empty cells when needed. Whitespace, commas, and newlines can be contained in quotation marks to count as a single value. To escape a quotation mark itself, use two quotation marks in a row: "" The seperator doesn't have to literally be a comma - tabs or semicolons are also frequently used, but any symbol unlikely to occur normally is fine. */ const char CVS_NoWhitespacing = '\0'; StringListArray StringToCSV(const std::string &str, char valueSeperator, char lineSeperator, CharValidatorFunc whitespaceFunc, bool keepRowsSameSize) { BUILD_NOTE("This could be better optimized. The quotation mark escaping and replacing is pretty horrible.") const std::string EscapedQuotationMark = "<quote>"; StringListArray csvFile; //If the string is empty, just return. if(str.empty()) return csvFile; //Keep track of how many columns there are. size_t maxColumns = 0; //Replace all two-in-a-row quotation marks with a special symbol. std::string completeFile = String::ReplaceAll(str, "\"\"", EscapedQuotationMark); //If the final line ends with a line seperator (like a newline), remove it. while(completeFile.back() == lineSeperator) completeFile.pop_back(); StringList lines = String::SeperateAndPreserve(completeFile, lineSeperator, '\"', String::KeepEmptySegments|String::KeepPreservationMarks); for(const auto &line : lines) { StringList values = String::SeperateAndPreserve(line, valueSeperator, '\"', String::KeepEmptySegments); for(auto &value : values) { value = String::RemovePadding(value, whitespaceFunc); //Add the quotation marks back in. value = String::ReplaceAll(value, EscapedQuotationMark, "\""); } maxColumns = std::max(maxColumns, values.size()); csvFile.emplace_back(std::move(values)); } //Resize every row to all have the same number of columns. if(keepRowsSameSize) { for(StringList &values : csvFile) { values.resize(maxColumns); } } return csvFile; } std::string CSVToString(const StringListArray &data, char valueSeperator, char lineSeperator, char whitespace) { std::string str; bool firstLine = true; for(const auto &line : data) { if(!firstLine) str += lineSeperator; firstLine = false; bool firstValue = true; for(auto value : line) { if(!firstValue) { str += valueSeperator; if(whitespace != CVS_NoWhitespacing) { str += whitespace; } } firstValue = false; //Replace all quotation marks with two in a row. value = String::ReplaceAll(value, "\"", "\"\""); if(String::Contains(value, valueSeperator)) { str += '\"' + value + '\"'; } else { str += value; } } } return str; } //Loads CSV data from a file. Returns an empty CSVFile if it fails. StringListArray LoadCSVFile(const std::string &filename, char valueSeperator, char lineSeperator, CharValidatorFunc whitespaceFunc, bool keepRowsSameSize) { return StringToCSV(LoadFileAsString(filename), valueSeperator, lineSeperator, whitespaceFunc, keepRowsSameSize); } //Saves CSV data to a file. Returns false if it fails. bool SaveCSVFile(const std::string &filename, const StringListArray &fileData, char valueSeperator, char lineSeperator, char whitespace) { return SaveStringAsFile(filename, CSVToString(fileData, valueSeperator, lineSeperator, whitespace)); }
Standard input is empty
prog.cpp:4:14: error: 'vector' in namespace 'std' does not name a template type
typedef std::vector<std::vector<std::string>> StringListArray; //In some header someplace
^
prog.cpp: In function 'bool SaveStringAsFile(const string&, const string&)':
prog.cpp:17:3: error: 'Log' has not been declared
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:17:44: error: 'Log' has not been declared
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:17:64: error: 'MSG_SOURCE' was not declared in this scope
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:17:138: error: 'GetFilenameFromPath' was not declared in this scope
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:17:139: error: 'Log_HighlightCyan' was not declared in this scope
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:17:179: error: 'Log_DisplayPath' was not declared in this scope
Log::Message(MSG_SOURCE("FileFunctions", Log::Severity::Error)) << "Failed to save '" << Log_HighlightCyan(GetFilenameFromPath(filename)) << "' at " << Log_DisplayPath(filename)
^
prog.cpp:18:125: error: 'Log' has not been declared
<< " for writing.\nDo I have sufficient privileges? Does the path exist? Is that file already in use?" << Log::FlushStream;
^
prog.cpp: At global scope:
prog.cpp:47:1: error: 'StringListArray' does not name a type
StringListArray StringToCSV(const std::string &str, char valueSeperator, char lineSeperator, CharValidatorFunc whitespaceFunc, bool keepRowsSameSize)
^
prog.cpp:95:31: error: 'StringListArray' does not name a type
std::string CSVToString(const StringListArray &data, char valueSeperator, char lineSeperator, char whitespace)
^
prog.cpp: In function 'std::string CSVToString(const int&, char, char, char)':
prog.cpp:101:25: error: 'begin' was not declared in this scope
for(const auto &line : data)
^
prog.cpp:101:25: note: suggested alternative:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
from /usr/include/c++/4.9/string:52,
from prog.cpp:1:
/usr/include/c++/4.9/initializer_list:89:5: note: 'std::begin'
begin(initializer_list<_Tp> __ils) noexcept
^
prog.cpp:101:25: error: 'end' was not declared in this scope
for(const auto &line : data)
^
prog.cpp:101:25: note: suggested alternative:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
from /usr/include/c++/4.9/string:52,
from prog.cpp:1:
/usr/include/c++/4.9/initializer_list:99:5: note: 'std::end'
end(initializer_list<_Tp> __ils) noexcept
^
prog.cpp:108:20: error: unable to deduce 'auto&&' from 'line'
for(auto value : line)
^
prog.cpp:123:12: error: 'String' has not been declared
value = String::ReplaceAll(value, "\"", "\"\"");
^
prog.cpp:125:7: error: 'String' has not been declared
if(String::Contains(value, valueSeperator))
^
prog.cpp: At global scope:
prog.cpp:140:1: error: 'StringListArray' does not name a type
StringListArray LoadCSVFile(const std::string &filename, char valueSeperator, char lineSeperator, CharValidatorFunc whitespaceFunc, bool keepRowsSameSize)
^
prog.cpp:146:53: error: 'StringListArray' does not name a type
bool SaveCSVFile(const std::string &filename, const StringListArray &fileData, char valueSeperator, char lineSeperator, char whitespace)
^
Standard output is empty