Это является ответом на несколько итераций этого вопроса, так что это может показаться немного отстаёт от того, что спросил выше.
Проблема заключается в том, что вы используете std::getline
прочитать до «:» характер. Затем вы используете перегруженный оператор >>
для std::string
, чтобы сделать еще одну запись в той же строке name
, перезаписывая ее. На этот раз он читает до конца строки.
После вызова std::getline
переменная name
содержит John.Smith
, а затем вы сразу же перезаписать это значение, выполнив input >> name;
. Это, по сути, то же самое, что и getline
, без возможности указания разделителя. Строка name
затем содержит 11:F12
, которую вы копируете в свой массив для последующего отображения.
Я думаю, что ваше замешательство в том, как были замечены работы getline
, вам не нужно было читать значение имени, используя >>
, он уже был в строке name
. Вам просто нужно было прочитать остальную часть строки и отбросить ее. Я рекомендую вам прочитать онлайн-ссылку для std::getline
, чтобы лучше понять, как она работает.
Чтобы устранить проблему, вы можете выполнить любое из следующих действий.
- ли еще «GetLine» или «>>» после того, как вы скопировали
name
в массив и отбросить значение, таким образом она очищает остальную часть линии, и вы затем прочитать следующее имя в вашем петельных getline
вызов. Немного взломанный способ достижения этого - переместить input >> name;
после строки, которая добавляет name
к массиву.
- Прочитайте всю строку без разделителя, а затем найдите (используя функцию-член
find
) первое вхождение ':' и возьмите подстроку до этого символа (используя функцию-член substr
).
- Определите структуру с именем & членов класса и прочитайте оба значения в структуре. Таким образом, вы намеренно читаете оба значения из файла. Если вам не нужна строка курса, это может быть излишним.
Некоторые коды, которые более или менее делают то, что я предлагаю.
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
void readNumbers(istream &input)
{
string array[10];
string name;
string garbage;
int i=0;
while(getline(input, name, ':'))
{
array[i]=name;
i++;
input >> garbage;
}
for(int i=0; i<10; i++) cout<< array[i] << '\n';
}
void readNumbers2(istream &input)
{
string array[10];
string ln;
int i=0;
while(getline(input, ln))
{
size_t colpos = ln.find(':');
if(colpos != string::npos)
{
array[i]=ln.substr(0, colpos);
i++;
}
}
for(int i=0; i<10; i++) cout<< array[i] << '\n';
}
struct studentinfo
{
string name;
string classref;
};
void readNumbers3(istream &input)
{
studentinfo array[10];
string name;
int i=0;
while(getline(input, array[i].name, ':'))
{
input >> array[i].classref;
i++;
}
for(int j=0; j < i; j++)
cout<< "name=" << array[j].name << '\n';
}
int main()
{
std::ifstream f("students.txt");
readNumbers(f);
}
Конечно, это лань не иметь дело с крайними случаями, например, пустые строки в файле или обгонной массив, но он демонстрирует использование std::getline
. Я также предлагаю вам посмотреть std::vector
или std::array
, чтобы удерживать ваши строки и использовать итераторы или диапазон, основанный на цикле, для печати значений.
Чтобы удалить двоеточие из строки, вы можете использовать следующий метод. используйте find
, чтобы найти индекс символов двоеточия и одну итераторную перегрузку string::erase
, чтобы удалить символ в этой позиции.
void charerase()
{
std::string s("15:F15");
std::cout << s << '\n';
size_t cpos = s.find(':');
if(cpos != std::string::npos)
{
s.erase(s.begin() + cpos);
}
std::cout << s << '\n';
}
Для этого вам нужно будет включать в себя заголовок <iterator>
.
Это действительно зависит от шаблона использования, нет? Как часто вы делаете запросы относительно обновлений, какие запросы вы делаете и т. Д. В качестве крайнего примера, если вы почти никогда не запрашиваете и не обновляете, вы можете использовать вектор, к которому вы добавляете материал в конце. –
Действительно, зависит от того, для чего вы хотите его сохранить - вы спрашиваете о сохранении или внутренней памяти? Ваш проект большой? Будете ли вы обновлять его чаще, чем запрос? У вас есть естественные ключи? –
@Lauren Вы должны задать новые вопросы, а не редактировать существующие, чтобы полностью изменить то, что его спрашивают. Теперь вы полностью отдалились от контекста. Вы получите более высокий рейтинг, задав больше вопросов, поэтому в ваших интересах это сделать. –