Во-первых, while (!reader.eof())
поступает неправильно .
Непосредственная проблема, которую вы видите, связана с тем, что ваш файл не содержит '\t'
, следовательно, уже самый первый getline
считывает все содержимое файла в tab[0]
. (По крайней мере, это то, что я получил после 1-к-1 копирования содержимого вашего файла)
Ваш код довольно сложен, потому что вы объявляете переменные задолго до того, как их используете, а затем снова используете. У вас есть массив фиксированного размера, но когда в файле будет больше строк, ваш код просто обработает sh. Также чтение всего в простой массив строк усложняет ситуацию. Доступ к forename
или другим полям требует, чтобы вы вычислили смещение в массиве. Лучше использовать структуру данных:
struct file_entry {
std::string first_name;
std::string last_name;
std::string departure;
std::string phone;
};
Затем вы можете определить оператор ввода:
std::istream& operator>>(std::istream& in,file_entry& fe) {
return in >> fe.first_name >> fe.last_name >> fe.departure >> fe.phone;
};
И использовать std::vector
, чтобы сохранить столько записей, сколько имеется в файле:
int main() {
std::string contents{"John Smith Sales 555-1234\n"
"Mary Jones Wages 555-9876\n"
"Paul Harris Accts 555-4321\n"};
std::stringstream reader{contents};
std::vector<file_entry> data;
std::string line;
while (std::getline(reader,line)) {
file_entry fe;
std::stringstream{line} >> fe;
data.push_back(fe);
}
for (const auto& fe : data) {
std::cout << "Forename: " << fe.first_name << '\n';
std::cout << "Surname: " << fe.last_name << '\n';
std::cout << "Department: " << fe.departure << '\n';
std::cout << "Telephone: " << fe.phone << '\n';
}
}
живой пример
PS вам не нужно вызывать close
для файла, это уже сделано в его деструкторе , Отсутствие явного вызова имеет то преимущество, что тот же код, который работает для файлового потока, также работает для потока строк.