您已成功读取文本文件中的数据并填充字符串数组。现在你需要做的是写一个解析函数来解析数组中的每个字符串或行。然后,在解析每一行时,您需要将每个内容保存到您的班级中。
我可以为您提供一个通用函数,它将为您解析字符串,前提是您使用的是相同的分隔符;它作为一个静态方法封装在一个Utility类中,以及一些其他有用的字符串操作函数。
Utility.h
#ifndef UTILITY_H
#define UTILITY_H
class Utility {
public:
static void pressAnyKeyToQuit();
static std::string toUpper(const std::string& str);
static std::string toLower(const std::string& str);
static std::string trim(const std::string& str, const std::string elementsToTrim = " \t\n\r");
static unsigned convertToUnsigned(const std::string& str);
static int convertToInt(const std::string& str);
static float convertToFloat(const std::string& str);
static std::vector<std::string> splitString(const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty = true);
private:
Utility(); // Private - Not A Class Object
Utility(const Utility& c); // Not Implemented
Utility& operator=(const Utility& c); // Not Implemented
template<typename T>
static bool stringToValue(const std::string& str, T* pValue, unsigned uNumValues);
template<typename T>
static T getValue(const std::string& str, std::size_t& remainder);
}; // Utility
#include "Utility.inl"
#endif // UTILITY_H
Utility.inl
// stringToValue()
template<typename T>
static bool Utility::stringToValue(const std::string& str, T* pValue, unsigned uNumValues) {
int numCommas = std::count(str.begin(), str.end(), ',');
if (numCommas != uNumValues - 1) {
return false;
}
std::size_t remainder;
pValue[0] = getValue<T>(str, remainder);
if (uNumValues == 1) {
if (str.size() != remainder) {
return false;
}
}
else {
std::size_t offset = remainder;
if (str.at(offset) != ',') {
return false;
}
unsigned uLastIdx = uNumValues - 1;
for (unsigned u = 1; u < uNumValues; ++u) {
pValue[u] = getValue<T>(str.substr(++offset), remainder);
offset += remainder;
if ((u < uLastIdx && str.at(offset) != ',') ||
(u == uLastIdx && offset != str.size()))
{
return false;
}
}
}
return true;
} // stringToValue
实用程序。CPP
#include "stdafx.h"
#include "Utility.h"
// pressAnyKeyToQuit()
void Utility::pressAnyKeyToQuit() {
std::cout << "Press any key to quit" << std::endl;
_getch();
} // pressAnyKeyToQuit
// toUpper()
std::string Utility::toUpper(const std::string& str) {
std::string result = str;
std::transform(str.begin(), str.end(), result.begin(), ::toupper);
return result;
} // toUpper
// toLower()
std::string Utility::toLower(const std::string& str) {
std::string result = str;
std::transform(str.begin(), str.end(), result.begin(), ::tolower);
return result;
} // toLower
// trim()
// Removes Elements To Trim From Left And Right Side Of The str
std::string Utility::trim(const std::string& str, const std::string elementsToTrim) {
std::basic_string<char>::size_type firstIndex = str.find_first_not_of(elementsToTrim);
if (firstIndex == std::string::npos) {
return std::string(); // Nothing Left
}
std::basic_string<char>::size_type lastIndex = str.find_last_not_of(elementsToTrim);
return str.substr(firstIndex, lastIndex - firstIndex + 1);
} // trim
// getValue()
template<>
float Utility::getValue(const std::string& str, std::size_t& remainder) {
return std::stof(str, &remainder);
} // getValue <float>
// getValue()
template<>
int Utility::getValue(const std::string& str, std::size_t& remainder) {
return std::stoi(str, &remainder);
} // getValue <int>
// getValue()
template<>
unsigned Utility::getValue(const std::string& str, std::size_t& remainder) {
return std::stoul(str, &remainder);
} // getValue <unsigned>
// convertToUnsigned()
unsigned Utility::convertToUnsigned(const std::string& str) {
unsigned u = 0;
if (!stringToValue(str, &u, 1)) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to unsigned";
throw strStream.str();
}
return u;
} // convertToUnsigned
// convertToInt()
int Utility::convertToInt(const std::string& str) {
int i = 0;
if (!stringToValue(str, &i, 1)) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to int";
throw strStream.str();
}
return i;
} // convertToInt
// convertToFloat()
float Utility::convertToFloat(const std::string& str) {
float f = 0;
if (!stringToValue(str, &f, 1)) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to float";
throw strStream.str();
}
return f;
} // convertToFloat
// splitString()
std::vector<std::string> Utility::splitString(const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty) {
std::vector<std::string> vResult;
if (strDelimiter.empty()) {
vResult.push_back(strStringToSplit);
return vResult;
}
std::string::const_iterator itSubStrStart = strStringToSplit.begin(), itSubStrEnd;
while (true) {
itSubStrEnd = search(itSubStrStart, strStringToSplit.end(), strDelimiter.begin(), strDelimiter.end());
std::string strTemp(itSubStrStart, itSubStrEnd);
if (keepEmpty || !strTemp.empty()) {
vResult.push_back(strTemp);
}
if (itSubStrEnd == strStringToSplit.end()) {
break;
}
itSubStrStart = itSubStrEnd + strDelimiter.size();
}
return vResult;
} // splitString
的包括需要这种类在stdafx.h
发现是:向量,字符串,CONIO.H,也许TCHAR.H,我也用这个枚举主的返回值这也是在发现stdafx.h
enum ReturnCode {
RETURN_OK = 0,
RETURN_ERROR = 1,
}; // ReturnCode
至于你Movie
类,你定义了你的函数来获取数据,但是你有没有表明您已经定义的任何设置方法,也没有构造函数。此外,你的getter应该被声明为const函数,因为这些函数不会改变存储在你的类对象中的数据。你的类应该是这样:
Movie.h
#ifndef MOVIE_H
#define MOVIE_H
class Movie {
private:
std::string m_strTitle;
std::string m_strYear;
std::string m_strGenre;
std::string m_strLength;
std::string m_Rating;
public:
Movie(); // Default Constructor
Movie(const std::string& strTitle, const std::string& strYear, const std::string& strGenre,
const std::string& strLength, const std::string& strRating();
std::string getTitle() const;
std::string getYear() const;
std::string getGenre() const;
std::string getLength() const;
std::string getRating() const;
void setTitle(const std::string& strTile);
void setYear(const std::string& strYear);
void setGenre(const std::string& strGenre);
void setLength(const std::string& strLength);
void setRating(const std::string& strRating);
private:
Movie(const Movie& c); // Not Implemented
Movie& operator=(const Movie& c); // Not Implemented
}; // Movie
#endif // MOVIE_H
Movie.cpp
#include "stdafx.h"
#include "Movie.h"
// Movie()
Movie::Movie() {
} // Movie
// Movie()
Movie::Movie(const std::string& strTitle, const std::string& strYear, const std::string& strGenre,
const std::string& strLength, const std::string& strRating) :
m_strTitle(strTitle),
m_strYear(strYear),
m_strGenre(strGenre),
m_strLength(strLength),
m_strRating(strRating) {
} // Movie
// getTitle()
std::string Movie::getTitle() const {
return m_strTitle;
} // getTitle
// getYear()
std::string Movie::getYear() const {
return m_strYear;
} // getYear
// getGenre()
std::string Movie::getGenre() const {
return m_strGenre;
} // GetGenre
// getLength()
std::string Movie::getLength() const {
return m_strLength;
} // getLength
// getRating()
std::string Movie::getRating() const {
return m_strRating;
} // getRating
// setTitle()
void Movie::setTitle(const std::string& strTile) {
m_strTitle = strTile;
} // setTitle
// setYear()
void Movie::setYear(const std::string& strYear) {
m_strYear = strYear;
} // setYear
// setGenre()
void Movie::setGenre(const std::string& strGenre) {
m_strGenre = strGenre;
} // setGenre
// setLength()
void Movie::setLength(const std::string& strLength) {
m_strLength = strLength;
} // setLength
// setRating()
void Movie::setRating(const std::string& strRating) {
m_strRating = strRating;
} // setRating
现在为您解析字符串使用功能的实用程序类Utility::splitString()
您需要为数组中的条目执行for循环,并且对于每次传递都必须分析该字符串,然后构造一个Movie对象ei然后使用其默认构造函数,然后填充每个成员或通过使用适当的构造函数构造对象。我将向您展示如何使用splitString()函数的示例。
的main.cpp
#include "stdafx.h"
#include "Utility.h"
#include "Movie.h"
int main() {
std::string test("Hello World How Are You Today");
std::vector<std::string>> vResults;
vResults = Utility::splitString(test, " ");
Utility::pressAnyKeyToQuit();
return RETURN_OK;
} // main
这里splitString将作为第一个参数是要分析该字符串作为其第二个参数的定界字符串或字符在你的情况下,它会是"|"
字符,它会将结果保存到一个字符串向量中。从这里开始for循环的每一遍,然后就是构造你的对象,同时为它们分配适当的值。
感谢您的深入解释和库。我想知道一些功能如何工作,看不到任何评论,对于我正在做的事情,我有点不适应。我是一名C++编程的初学者,目前我的知识基础略高于 – KingShahmoo
@KingShahmoo上面编写的大部分代码并不需要评论函数或方法做他们所说的。我提供的Utility类中唯一重要的函数是splitString()方法。 –
@KingShahmoo你所做的是从文件中读取一行文本并将其保存到一个字符串中,并且你已经完成了保存在你的数组中的所有字符串。下一步是逐个取出该数组中的每个字符串,并在每次循环中解析该字符串。我刚刚给你的实用工具类将基于分隔文本行的分隔字符解析此字符串。最后一步是创建您的Movie对象并传入所需的数据。 –