Индексирование 2D-вектора приводит к сбою моей программы

#c #vector #2d-vector

#c #вектор #2d-вектор

Вопрос:

Я беру входные данные из текстового файла и сохраняю их в 2D-векторе. Эта часть работает нормально. Кажется, что моя программа выдает ошибку, как только я пытаюсь получить доступ к отдельным элементам 2D-вектора. Из того, что я искал, я правильно индексирую вектор, так что кто-нибудь знает, почему это приведет к сбою моего кода?

редактировать: я правильно обращаюсь к вектору. getInput2D() на самом деле не удается добавить temp_vec к output_vector. Каким был бы правильный синтаксис для динамического создания 2D-вектора в этой ситуации?

 #include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include <vector.>
#include <cmath>

using namespace std;

vector<vector<string>> output_vector{};

void getInput2D() { 
    
    ifstream file("C:\Users\ImTheUser\Documents\input.txt");
    string line;
    vector<string> temp_vec;
    
    if (file.is_open()) { 
        while (getline(file, line)) {
            if (line[0] != ' ') {
                temp_vec.push_back(line);
                temp_vec.clear();
            }

            else {
                output_vector.push_back(temp_vec);
                temp_vec.clear();
            }
        }
    }
    file.close();
}

int main() {
    
    getInput2D();
    cout << output_vector[0][0] << endl;
    return 0;
}
 

Комментарии:

1. вы должны проверить размер output_vector , а затем проверить размер его второго подвектора перед доступом [1][2] . В зависимости от содержимого файла вектор может содержать меньше элементов, чем вы думаете

2. кстати, вы никогда не очищаете temp_vec so, в конце output_vector концов, будет содержать одни и те же line s несколько раз

3. Программа вылетает, когда я обращаюсь к любому индексу, обновил код для доступа к [0] [0] с теми же результатами

4. Разве строки не начинаются с пробела? Если это так, вы никогда не добавите temp_vec output_vector . С учетом сказанного @largest_prime_is_463035818 выявил 2 потенциальные проблемы в коде, которые вам, вероятно, следует исправить и повторно протестировать.

5. После output_vector.push_back(temp_vec); того, как вы должны сделать temp_vec.clear(); , и до или после file.close(); того, как вы должны сделать output_vector.push_back(temp_vec); . По этому вопросу вам вообще не нужно file.close(); . Деструктор для ifstream закроет файл для вас.

Ответ №1:

Я правильно индексирую вектор, так кто-нибудь знает, почему это приведет к сбою моего кода?

Предполагая, что вы абсолютно уверены, что output_vector у него 1 или более элементов и что его первый элемент имеет 1 или более элементов, это правильный способ доступа к ним:

 cout << output_vector[0][0] << endl;
 

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

 for (const autoamp; lines : output_vector) {
    for (const autoamp; line : lines) {
        std::cout << line << 'n';
    }
}
 

для печати всех элементов, которые на самом деле находятся в векторе. Или проверьте его размер, прежде чем:

 if (output_vector.size() > 0 amp;amp; output_vector[0].size() > 0) {
     std::cout << output_vector[0][0];
} else {
     std::cout << "error. output_vector is emptyn";
}
 

Комментарии:

1. Это и есть ответ. Я предположил, что push_back() на самом деле добавлял temp_vec к output_vector, но, попробовав оба подхода, я могу с уверенностью сказать, что output_vector пуст после запуска getInput2D(), поэтому я правильно обращаюсь к вектору, но неправильно создаю output_vector.

2. @Schteve возможно, мне следовало бы подчеркнуть это больше. Важный момент: даже если вы заставите свой код работать и cout << output_vector[0][0] << endl; делать то, что вы ожидаете, вы не должны предполагать, что он работает для всех входных данных из файла. При чтении из файла учитывайте, что что-то идет не так, и восстановление после ошибки намного проще, если учесть это с самого начала, а не только тогда, когда ошибка уже произошла. Т.е. проверяйте размер output_vector абы как, даже если вы «знаете», что он правильно заполнен из файла