您已成功讀取文本文件中的數據並填充字符串數組。現在你需要做的是寫一個解析函數來解析數組中的每個字符串或行。然後,在解析每一行時,您需要將每個內容保存到您的班級中。
我可以爲您提供一個通用函數,它將爲您解析字符串,前提是您使用的是相同的分隔符;它作爲一個靜態方法封裝在一個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對象並傳入所需的數據。 –