Наиболее вероятной причиной сбоя является то, что "Measured-Isotopes.txt"
не находится в текущем рабочем каталоге при запуске вашей программы, что приводит к сбою ifstream in("Measured-Isotopes.txt");
.
Для любой операции ввода/вывода, включая открытие файла, вы должны всегда проверять состояние потока после каждой операции. В вашем случае вы хотели бы как минимум подтвердить успешное открытие, например
if (!in.good()) {
std::cerr << "error: file open failed.\n";
return;
}
Возможно, вы захотите пересмотреть рефакторинг своего кода, чтобы указать имя файла для чтения в качестве первого аргумента программы (для этого int main (int argc, char **argv)
) или предложить пользователю ввести имя файла и прочитать имя файла в качестве входных данных. Вам не нужно перекомпилировать свой код просто для чтения из файла с другим именем.
Кроме того, рассмотрите возможность открытия файлового потока в вызывающей функции (main()
здесь) и передачи ссылки на открытый файловый поток в качестве аргумента функции. Если открыть файл не удается, для начала нет необходимости вызывать функцию.
При таком подходе вы могли бы написать свою функцию duplicate()
как:
#include <iostream>
#include <fstream>
#include <vector>
/* since I/O is performed in function, providing a return type that can
* indicate success/failure is useful.
*/
bool duplicate (std::ifstream& in, std::vector<std::pair<int, int>>& vec)
{
int A, Z;
while (in >> A && in >> Z){
vec.push_back((std::make_pair(A, Z)));
}
if(vec.empty()){
return false;
}
return true;
}
(примечание: тип возвращаемого значения изменен на bool
, поэтому успех/неудача чтения указывается через возврат)
Затем вы можете записать свой main()
как
int main (int argc, char **argv) {
if (argc < 2) { /* validate at least 1 argument given */
std::cerr << std::string {"error: insufficient arguments\n"
"usage: "} + argv[0] + " filename\n";
return 1;
}
std::vector<std::pair<int, int>> vec;
std::ifstream in (argv[1]); /* open file */
if (!in.good()) { /* validate open succeeds */
std::cerr << "error: file open failed.\n";
return 1;
}
if (duplicate (in, vec)) { /* pass open stream, reference to vec, validate return */
for (const auto p : vec) { /* output vec contents on success */
std::cout << p.first << ", " << p.second << '\n';
}
}
else { /* handle error on failure */
std::cout << "oops - vector empty\n";
}
}
(примечание: использование '\n'
вместо std::endl
, см. Things std::endl
приводит к очистке выходного буфера))
Пример использования/вывода
С вашими данными в файле dat/vectpairs.txt
вы получите:
./bin/vect_read_pairs dat/vectpairs.txt
10, 8
5, 6
15, 4
Посмотрите и дайте мне знать, если у вас есть вопросы.
Какое доказательство вы можете предоставить, доказывающее, что в текущем каталоге процесса, выполняющего скомпилированный код, есть файл с именем «Measured-Isotopes.txt»?
Почему у вас нет
if (!in.good()) { std::cerr << "error: file open failed.\n"; return; }
для проверки открытия файла? (PS -- не используйте MagicNumbers или жестко закодированные имена файлов в своем коде) ... вы хорошо разбираетесь в MagicNumbers, но не так в жестко закодированном имени файла...Несвязанный: вместо
vec.push_back((std::make_pair(A, Z)));
вы можете просто сделатьvec.emplace_back(A, Z);
@Zach Finger убедитесь, что файл открывается. В противном случае ваш код выглядит правильно.