C ++ не может вернуть все переменные, которые были добавлены в список векторов - PullRequest
1 голос
/ 15 апреля 2020

В программе, которую я сейчас пишу, я до стадии, которая требует использования данных, которые были прочитаны через файл. Некоторые из этих данных содержат числовые элементы, поэтому были выполнены соответствующие преобразования, чтобы сохранить их в векторе строки типа. До этого момента работает.

У меня есть функция robotComplexity, которая вычисляет значение на основе других значений, найденных в файле, которые уже были добавлены в векторный список (весь код будет опубликован ниже). Текстовый файл содержит следующие данные.

A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.

Как видно из приведенного ниже кода, этот файл был разделен с помощью разделителя в двоеточии и полной остановки, чтобы сначала отделить переменные, а затем записи. Переменные были сохранены в соответствующих держателях, как показано в коде. Функция с именем robotComplexity содержит значение для l oop

for(std::size_t i=0; i< partsVector.size(); ++i) { 
 if(partsVector[i] == userChoice) {
   cout << userChoice << stoi(stringMaximum) << endl;
   }

Проблемы с моим кодом связаны с этим для l oop. Программа может l oop через файл и повторно определить первую переменную partCode (преобразованную в newChar) соответствующих значений A, B, C, D, E. Так, например, когда пользователь вводит A, он возвращает A, вводит B, возвращает B et c. Теперь мои проблемы связаны с попыткой распечатать другие переменные, хранящиеся в векторе. В строке cout << userChoice ... et c он успешно возвращает букву (пример A), но не возвращает правильное значение для stringMaximum, преобразованное в int. Возвращаемое значение равно 0, где оно должно быть равно значению для partCode A (в данном случае) </p>

Я спрашиваю, может ли кто-нибудь создать / исправить my для l oop, чтобы при cout << "Variable" вызывается, он может успешно вывести на консоль значение этой переменной в соответствии с partCode </p>

Например, если пользователь вводит A в качестве кода детали, вывод должен быть

code

cout << userChoice << partName << stringMaximum  << stringMinimum << stringComplexity << endl;

вывод

A 
Head 
1 
2 
15

файл, содержащий функции

struct Part {
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
} myPart;

std::vector<string> partsVector;
std::ifstream partsList("Parts.txt");

std::string outputFile = "output.txt";
std::string input;

std::string newChar;
std::stringstream convertChar;

std::string stringMaximum = std::to_string(myPart.maximum);
std::string stringMinimum = std::to_string(myPart.minimum);
std::string stringComplexity = std::to_string(myPart.complexity);

void readFile() //function to read Builders, Customers and Parts text file
{
 std::string line;

while (std::getline(partsList, line)) {
    line.pop_back();//removing '.' at end of line
    std::string token;
    std::istringstream ss(line);

    convertChar << myPart.partCode;
    convertChar >> newChar;

    // then read each element by delimiter
    int counter = 0;//number of elements you read
    while (std::getline(ss, token, ':')) {//spilt into different records
      switch (counter) {//put into appropriate value-field according to element-count

      case 0:
        newChar = token; //convert partCode from a char to a string 
        break;
      case 1:
        myPart.partName = token;
        break;
      case 2: 
      myPart.maximum =stoi(token);
        break;
      case 3: 
      myPart.minimum = stoi(token);
        break;
        case 4:
         myPart.complexity = stoi(token);
        break;
      default:
        break;
      }
      counter++;//increasing counter
    }

partsVector.push_back(newChar);
partsVector.push_back(myPart.partName);
partsVector.push_back(stringMaximum);
partsVector.push_back(stringMinimum);
partsVector.push_back(stringComplexity);

   } 
}

double robotComplexity() { 

double complexity;
string userChoice;

cout << "Enter a part code A ,B ,C ,D or E" << endl;
cin >> userChoice;

for(std::size_t i=0; i< partsVector.size(); ++i) { 
 if(partsVector[i] == userChoice) {
   cout << userChoice << stoi(stringMaximum) << endl;
   }
} 
} 

Спасибо за любую помощь. Если вам нужны какие-либо объяснения, пожалуйста, не стесняйтесь спрашивать. PS Я знаю, что глобальные переменные не лучше всего использовать, но как только мои функции будут работать правильно, я уберу код с локальных переменных.

1 Ответ

3 голосов
/ 15 апреля 2020

Здесь есть несколько проблем, но ваша главная проблема в том, что

std::string stringMaximum = std::to_string(myPart.maximum);
std::string stringMinimum = std::to_string(myPart.minimum);
std::string stringComplexity = std::to_string(myPart.complexity);

являются глобальными переменными, а не функциями. Они будут оцениваться только один раз в начале вашей программы. Так что ваш readFile уже сломан в коде, который вы нам дали. Первое, что я хотел бы сделать, это удалить глобальное состояние (т.е. удалить все глобальные переменные) и исправить код, который больше не компилируется.

Вы делаете

partsVector.push_back(stringMaximum);
partsVector.push_back(stringMinimum);

в readFile не устанавливая эти две переменные, так что вы всегда получаете sh одно и то же значение в вашем векторе.

Следующий вопрос: почему вы используете вектор строки, а не вектор части? Вы уже анализируете файл для Part объектов, поэтому просто используйте их. Кроме того, вы хотите получить доступ к этим частям через пользовательский ввод, который запрашивает Part.partCode, поэтому мы можем использовать справочную таблицу с ключом partCode (в данном случае std::unordered_map<char, Part>).

Все в все это выглядело бы следующим образом (внутреннее время l oop в readFile тоже было кошмаром, поэтому я убрал это также):

#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
#include <unordered_map>

struct Part
{
    char partCode = 0;
    std::string partName;
    int maximum = 0;
    int minimum = 0;
    int complexity = 0;
};

std::stringstream partsList(
    R"(A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.)");

std::string outputFile = "output.txt";
std::string input;

std::unordered_map<char, Part> readFile() //function to read Builders, Customers and Parts text file
{
    std::unordered_map<char, Part> parts;
    std::string line;

    while (std::getline(partsList, line))
    {
        line.pop_back(); //removing '.' at end of line
        std::string token;
        std::istringstream ss(line);
        Part part;

        std::getline(ss, token, ':');
        part.partCode = token[0];
        std::getline(ss, part.partName, ':');
        std::getline(ss, token, ':');
        part.maximum = std::stoi(token);
        std::getline(ss, token, ':');
        part.minimum = std::stoi(token);
        std::getline(ss, token, ':');
        part.complexity = std::stoi(token);

        parts.emplace(part.partCode, std::move(part));
    }

    return parts;
}

double robotComplexity(std::unordered_map<char, Part> const& parts)
{
    double complexity = 10;
    char partCode;

    std::cout << "Enter a part code A ,B ,C ,D or E" << std::endl;
    std::cin >> partCode;

    auto const& part = parts.at(partCode);
    std::cout << part.maximum;

    if (complexity > 100)
    {
        complexity = 100;
    }

    std::cout << "\nThe Robot Complexity is: " << complexity << std::endl;
    return complexity;
}

void writeFile() //writes to a file output.txt the end calculations.
{
}

int main()
{
    auto parts = readFile();
    writeFile();
    robotComplexity(parts);
    return 0;
}
...