Вектор не заполняет информацию в моем текстовом файле С++

avatar
Zach Finger
9 августа 2021 в 01:05
88
3
0

Привет, я пытаюсь заполнить вектор информацией из текстового файла. Текстовый файл выглядит примерно так:

10  8
5  6
15  4

Я написал код на C++, пытаясь сделать это, но он не заполняется. Вот мой код:

#include <iostream>
#include <fstream>
#include <vector>
void duplicate() {
  ifstream in("Measured-Isotopes.txt");
  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()){
    cout<<"oops"<<endl;
  }

}
Источник
Sam Varshavchik
9 августа 2021 в 01:09
2

Какое доказательство вы можете предоставить, доказывающее, что в текущем каталоге процесса, выполняющего скомпилированный код, есть файл с именем «Measured-Isotopes.txt»?

David C. Rankin
9 августа 2021 в 01:10
4

Почему у вас нет if (!in.good()) { std::cerr << "error: file open failed.\n"; return; } для проверки открытия файла? (PS -- не используйте MagicNumbers или жестко закодированные имена файлов в своем коде) ... вы хорошо разбираетесь в MagicNumbers, но не так в жестко закодированном имени файла...

Ted Lyngmo
9 августа 2021 в 01:23
2

Несвязанный: вместо vec.push_back((std::make_pair(A, Z))); вы можете просто сделать vec.emplace_back(A, Z);

zois
9 августа 2021 в 01:28
1

@Zach Finger убедитесь, что файл открывается. В противном случае ваш код выглядит правильно.

Ответы (3)

avatar
Zach Finger
9 августа 2021 в 01:48
0

Оказывается, проблема заключалась в том, что моя первая строка в текстовом файле была меткой, которая была строкой, поэтому, поскольку я сделал свой вектор 2 целыми числами, он испортился и не заполнялся. Я удалил ярлык, и теперь он заполняется нормально.

avatar
David C. Rankin
9 августа 2021 в 01:32
3

Наиболее вероятной причиной сбоя является то, что "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

Посмотрите и дайте мне знать, если у вас есть вопросы.

avatar
secuman
9 августа 2021 в 01:30
3

Ваш код не вызывает проблем в моей среде. Я использую Visual Studio 2017.
Убедитесь, что файл существует в той же папке, что и ваша программа.

std::ifstream in("Measured-Isotopes.txt");
if (!in.is_open())
{
    std::cout << "File is not exist" << std::endl;
    return;
}
Zach Finger
9 августа 2021 в 01:39
0

Это очень странно. Я вставил это выражение if, и оно не печаталось. FIle не существует, поэтому файл определенно существует и открывается. Возможно ли, что A и Z не соответствуют первому и второму столбцу?

Zach Finger
9 августа 2021 в 01:42
0

Я пытаюсь кое-что. Я воссоздаю текстовый файл, потому что понял, что первая строка текстового файла - это метки, которые являются строками, поэтому они могут его испортить.

secuman
9 августа 2021 в 01:44
0

Какая кодировка txt файла? Если он закодирован в Unicode, вы увидите сообщение «oops». Пожалуйста, подтвердите кодировку txt файла UTF8 или ANSI.