Цель: Считайте числовые текстовые файлы в векторы, а затем добавьте векторы в ключ, значение std::map, чтобы я мог ссылаться на них по имени ключа, которое я указал для них позже.
Думал, что это будет легко, и я удивлен, что не могу найти ответ на это уже в StackOverflow.
Ожидаемый результат:
Print1 = {100,200,500,600}
Print2 = {7890,5678,34567,3,56}
Print3["NameA"] = Print1
Print3["NameB"] = Print2
Если мой процесс неэффективен или идет в неправильном направлении, я был бы признателен за указатели.
Я продолжаю получать ошибки сборки Semantic Issue, и нет жизнеспособного преобразования из pair <const basic_string>
Текущий код:
#include <string.h>
#include <iostream>
#include <map>
#include <utility>
#include <vector>
const std::string& key(const std::pair<std::string, std::string>& keyValue)
{
return keyValue.first;
}
const std::string& value(const std::pair<std::string, std::string>& keyValue)
{
return keyValue.second;
}
int main()
{
std::vector<int> print1;
std::ifstream inputFile("numbers.txt");
// test file open
if (inputFile)
{
double value;
// read the elements in the file into a vector
while ( inputFile >> value ) {
print1.push_back(value);
}
}
inputFile.close();
std::vector<int> print2;
std::ifstream inputFile2("numbers2.txt");
// test file open
if (inputFile2)
{
double value;
// read the elements in the file into a vector
while ( inputFile2 >> value ) {
print2.push_back(value);
}
}
inputFile2.close();
std::map<std::string, std::vector<int>> contacts;
contacts["alice"] = print1;
contacts["bob"] = print2;
std::vector<std::string> keys(contacts.size());
std::vector<int> values(contacts.size());
transform(contacts.begin(), contacts.end(), keys.begin(), key);
transform(contacts.begin(), contacts.end(), values.begin(), value);
std::cout << "Keys:\n";
copy(keys.begin(), keys.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
std::cout << "\n";
std::cout << "Values:\n";
copy(values.begin(), values.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
Если ваш компилятор не сообщает вам, в какой строке возникает ошибка, выбросьте ее и получите ту, которая сообщает. Но учитывая, что Xcode - серьезный инструмент, которым пользуется множество людей, мне трудно поверить, что он выдает ошибку без ссылки на строку.
Если вы не можете понять, как использовать вашу среду IDE, чтобы сообщить вам номер строки, просто попробуйте закомментировать разные части, пока не разберетесь.
Вы прошли? Не получается? Я думал, ты не сможешь скомпилировать. Как можно выполнить программу, которая не компилируется? И как он мог не скомпилироваться на такой тривиальной строчке, как создание карты?
@ user3152377 что именно, key(const std::pair<std::string, std::string>& keyValue) и value(const std::pair<std::string, std::string>& keyValue) в вашем std::transform? И почему, если программа не смогла открыть файл; вы закроете, не считаясь с этим, не так ли?
@ user3152377, если ваш комментарий, начинающийся с это читается как ..., является сообщением об ошибке компиляции, отредактируйте исходное сообщение, чтобы добавить этот текст. Это избавит ваших читателей от необходимости рыться во всех комментариях, чтобы найти нужную информацию. Я не знаком с Xcode, но предполагаю, что 2031 г. - это номер вашей строки, а 26 - номер вашего столбца в файле алгоритм.





Прежде всего, нет смысла утверждать, что Xcode не показывал никаких сообщений об ошибках для вашего кода. Попробуйте либо включить все предупреждения компилятора, либо попробуйте онлайн-компиляторы. Результат не разочарует: https://godbolt.org/z/cU54GX
Если я правильно понял, вы хотите сохранить свою информацию из двух файлов (целочисленные значения) в std::map, где его ключ = std::string и значение = vector of integer array.
Если так,
1. У вас проблема, начиная с чтения целых чисел из файлов.
Здесь вы используете double без причины и сохраняете его в
std::vector<int> (т.е. print1 и print2).
2. Во-вторых, что делать, если ваш файл не был открыт? inputFile.close();
и inputFile2.close(); все равно закроет его, не зная
факт. Это не правильно.
Правильный способ:
inputFile.open("numbers.txt", std::ios::in); // opening mode
if (inputFile.is_open()) {
// do stuff
inputFile.close(); // you need closing only when file has been opened
}
3. Если вы намерены печатать только keys и values, вы не
нужно разобрать их на разные векторы.
Вы можете сделать это напрямую:
for(const std::pair<kType, vType>& mapEntry: contacts)
{
std::cout << "Key: " << mapEntry.first << " Values: ";
for(const int values: mapEntry.second) std::cout << values << " ";
std::cout << std::endl;
}
В С ++ 17 вы можете использовать Структурированная привязка
for(const auto& [Key, Values]: contacts)
{
std::cout << "Key: " << Key << " Values: ";
for(const int value: Values) std::cout << value << " ";
std::cout << std::endl;
}
4. Если вы действительно хотите разобрать их на другой вектор; во-первых, неправильная структура данных для хранения keys:
std::vector<int> values(contacts.size());
^^^^^^
который должен был быть вектором вектора целых чисел, как ваш vType = std::vector<int>. Это,
std::vector<std::vector<int>> values
^^^^^^^^^^^^^^^^^^
Во-вторых, у вас неправильные функции key(const std::pair<std::string, std::string>& keyValue) и value(const std::pair<std::string, std::string>& keyValue), где вы передаете пара струн в качестве ключей и значений.
Это должно было быть
typedef std::string kType; // type of your map's key
typedef std::vector<int> vType;// value of your map's value
std::pair<kType, vType>
Однако вы можете просто заменить лямбда-выражения, что будет более интуитивно понятным в том смысле, что функции будут располагаться рядом с нужной строкой. Например,
std::vector<kType> keysVec;
keysVec.reserve(contacts.size());
auto getOnlyKeys = [](const std::pair<kType, vType>& mapEntry){ return mapEntry.first; };
std::transform(contacts.begin(), contacts.end(), std::back_inserter(keysVec), getOnlyKeys);
Я очень ценю предложение онлайн-компилятора и указатели на то, где мой код дает сбой и может быть более эффективным. Спасибо за продвижение моих знаний о C++.
Вы можете напрямую ссылаться на элемент карты, который создаст запись, если она не существует, и просто заполните ее из цикла чтения файла:
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <string>
int main()
{
std::map<std::string, std::vector<int>> m;
int num;
auto &&alice = m["alice"];
std::ifstream if_alice("numbers1.txt");
while (if_alice >> num)
alice.push_back(num);
if_alice.close();
auto &&bob = m["bob"];
std::ifstream if_bob("numbers2.txt");
while (if_bob >> num)
bob.push_back(num);
if_bob.close();
// test
for (auto &&data : m)
{
std::cout << "Name: " << data.first << "\t";
for (int num : data.second)
std::cout << num << " ";
std::cout << "\n";
}
}
Красиво и оперативно! Спасибо.
Похоже, ваш код не компилируется. Опубликуйте одну строку кода, при компиляции которой у вас возникли проблемы, а не всю программу.