Dosyanızı ikili veya metin olarak okuyor musunuz bilmiyorum; ama cevabım içinde bir metin satırındaki her alanın bir boşluk karakteri ile ayrıldığı bir metin dosyasından okuyorum. Aradığınızı, uygun bir çalışma programını derlemek ve oluşturmak için gerekli tüm dosyaları ekleyeceğim. Bunlardan bazıları gerekli olmayabilir, ancak bunlar için uygun bir şekilde oluşturulmasına dayanan daha büyük bir projeye sahip olduğum çözümümün içindedir.
stdafx.h
#ifndef STDAFX_H
#define STDAFX_H
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <memory>
#include <queue>
#include <functional>
#include <algorithm>
// User Application Specific
// #include "ExceptionHandler.h" // Required For My Solution But Isn't Used In Yours
namespace util {
enum ReturnCode {
RETURN_OK = 0,
RETURN_ERROR = 1,
}; // ReturnCode
extern const unsigned INVALID_UNSIGNED;
extern const unsigned INVALID_UNSIGNED_SHORT;
} // namespace util
#endif // STDAFX_H
Stdafx.cpp
#include "stdafx.h"
namespace util {
const unsigned INVALID_UNSIGNED = static_cast<const unsigned>(-1);
const unsigned INVALID_UNSIGNED_SHORT = static_cast<const unsigned short>(-1);
} // namespace util
Utility.h
#ifndef UTILITY_H
#define UTILITY_H
namespace util {
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"
} // namespace util
#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
Utility.cpp
#include "stdafx.h"
#include "Utility.h"
namespace util {
// ----------------------------------------------------------------------------
// 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
} // namspace util
CharacterData.h
#ifndef CHARACTER_DATA_H
#define CHARACTER_DATA_H
class CharacterData {
private:
std::string m_name;
float m_health;
unsigned m_exp;
public:
CharacterData();
CharacterData(const std::string& name, float health, unsigned exp);
void setName(const std::string& name);
void setHealth(float health);
void setExperience(unsigned exp);
std::string getName() const;
float getHealth() const;
unsigned getExperience() const;
private:
CharacterData(const CharacterData& c); // Not Implemented
CharacterData& operator=(const CharacterData& c); // Not Implemented
}; // CharacterData
#endif // CHARACTER_DATA_H
CharacterData.cpp
#include "stdafx.h"
#include "CharacterData.h"
// ----------------------------------------------------------------------------
// CharacterData()
CharacterData::CharacterData() :
m_name(std::string()),
m_health(0.0f),
m_exp(0) {
} // CharacterData
// ----------------------------------------------------------------------------
// CharacterData()
CharacterData::CharacterData(const std::string& name, float health, unsigned exp) :
m_name(name),
m_health(health),
m_exp(exp) {
} // CharacterData
// ----------------------------------------------------------------------------
// setName()
void CharacterData::setName(const std::string& name) {
m_name = name;
} // setName
// ----------------------------------------------------------------------------
// getName()
std::string CharacterData::getName() const {
return m_name;
} // getName
// ----------------------------------------------------------------------------
// setHealth()
void CharacterData::setHealth(float health) {
m_health = health;
} // setHealth
// ----------------------------------------------------------------------------
// getHealth()
float CharacterData::getHealth() const {
return m_health;
} // getHealth
// ----------------------------------------------------------------------------
// setExperience()
void CharacterData::setExperience(unsigned exp) {
m_exp = exp;
} // setExperience
// ----------------------------------------------------------------------------
// getExperience()
unsigned CharacterData::getExperience() const {
return m_exp;
} // getExperience
CharacterDatabase.h
#ifndef CHARACTER_DATABASE_H
#define CHARACTER_DATABASE_H
class CharacterData;
class CharacterDatabase {
private:
std::string m_filename;
std::vector<std::shared_ptr<CharacterData>> m_vpCharacters;
public:
explicit CharacterDatabase(const std::string& filename);
// ~CharacterDatabase(); // Default Okay
void displayByOption(unsigned option = 0);
private:
CharacterDatabase(const CharacterDatabase& c); // Not Implemented
CharacterDatabase& operator=(const CharacterDatabase& c); // Not Implemented
void parseFile();
void display() const;
static bool sortByName(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2);
static bool sortByHealth(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2);
static bool sortByExperience(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2);
}; // CharacterDataase
#endif // CHARACTER_DATABASE_H
Characterdatabase.cpp
#include "stdafx.h"
#include "CharacterDatabase.h"
#include "CharacterData.h"
#include "Utility.h"
// ----------------------------------------------------------------------------
// CharacterDatabase()
CharacterDatabase::CharacterDatabase(const std::string& filename) :
m_filename(filename) {
parseFile();
} // CharacterDatabase
// ----------------------------------------------------------------------------
// parseFile()
void CharacterDatabase::parseFile() {
using namespace util;
if (m_filename.empty()) {
std::cout << "Missing or invalid filename." << std::endl;
return;
}
std::string line;
std::vector<std::string> results;
std::ifstream in;
// Try To Open File For Reading
in.open(m_filename.c_str(), std::ios_base::in);
if (!in.is_open()) {
std::cout << "Can not open file(" << m_filename << ") for reading.";
return;
}
// Read Line By Line And Store Contents Into String & Parse Each Line One At A Time.
while (!in.eof()) {
std::getline(in, line);
results = Utility::splitString(line, " ");
// On Each Pass We Want To Construct A CharacterData Object & Save It Into Our Container
m_vpCharacters.push_back(std::make_shared<CharacterData>(results[0], Utility::convertToFloat(results[1]), Utility::convertToUnsigned(results[2])));
}
// Close File Pointer
in.close();
} // parseFile
// ----------------------------------------------------------------------------
// display()
void CharacterDatabase::display() const {
for (unsigned u = 0; u < m_vpCharacters.size(); u++) {
std::cout << m_vpCharacters[u]->getName() << "\t"
<< m_vpCharacters[u]->getHealth() << "\t"
<< m_vpCharacters[u]->getExperience() << std::endl;
}
std::cout << std::endl;
} // display
// ----------------------------------------------------------------------------
// displayByOption() Default 0 = Order In Which File Is Read In,
// 1 = Sorted By Name, 2 = Sorted By Health, 3 = Sorted By Experience
void CharacterDatabase::displayByOption(unsigned option) {
switch (option) {
case 1: { // Sorted By Name
std::sort(m_vpCharacters.begin(), m_vpCharacters.end(), sortByName);
display();
break;
}
case 2: { // Sorted By Health
std::sort(m_vpCharacters.begin(), m_vpCharacters.end(), sortByHealth);
display();
break;
}
case 3: { // Sorted By Experience
std::sort(m_vpCharacters.begin(), m_vpCharacters.end(), sortByExperience);
display();
break;
}
default: { // Unsorted - Order Read In By File
display();
}
}
} // displayByOption
// ----------------------------------------------------------------------------
// sortByName()
bool CharacterDatabase::sortByName(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2) {
return d1->getName() < d2->getName();
} // sortByName
// ----------------------------------------------------------------------------
// sortByHealth()
bool CharacterDatabase::sortByHealth(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2) {
return d1->getHealth() < d2->getHealth();
} // sortByHealth
// ----------------------------------------------------------------------------
// sortByExperience()
bool CharacterDatabase::sortByExperience(const std::shared_ptr<CharacterData>& d1, const std::shared_ptr<CharacterData>& d2) {
return d1->getExperience() < d2->getExperience();
} // sortByExperience
characterData.txt
Alice 23.
Xander 45.3 1110
Bernard 12.9 2024
Yanni 23.7 1098
Craw 50.5 980
Zack 11.9 1024
main.cpp
#include "stdafx.h"
#include "Utility.h"
#include "CharacterDatabase.h"
int main() {
using namespace util;
CharacterDatabase cd("characterData.txt");
cd.displayByOption();
cd.displayByOption(1);
cd.displayByOption(2);
cd.displayByOption(3);
Utility::pressAnyKeyToQuit();
return RETURN_OK;
} // main
Sadece yapmak kullanırken de doğru yoldan dosyayı çağırarak emin Utility :: splitString() yöntemi, ikinci parametre veya sınırlayıcı mat olduğundan emin olun saklanan dosyanızda sahip olduğunuz şey. SplitString() yöntemi, karakterin her göründüğünde dizenin her satırından dizeyi böler. Tek bir dize saklamak istediğiniz ilk adın ilk & soyadı gibi birden çok adı varsa, o zaman biraz daha dikkat gerekir.
Neden bir "charData" dizisini değil, bir 2B dizisine mi ihtiyacınız var? – Anedar
Eğer garip bir şey söylersem özür dilerim. Ben bir C++ noob'um. Bilginin bir satır ve sütunlarda tutulması istedim – William
Bu soru bir [mcve] gereksinimlerini karşılayamıyor. Lütfen sorunuzu düzenleyin, böylece bir [mcve] içerir. Bunu yapana kadar yetkili bir cevap alacağınız pek olası değil. –