2016-04-13 2 views
-2

У меня есть файл, который включает в себя имя кого-то, то, конечно, они где в и реестромКак правильно использовать функцию станд :: GetLine

экс. John.smith: 11: F12

В настоящее время выхода это

George.Clooney 

Jennifer.Lawrence 

Kevin.Bacon 


15:S13 

15:F15 

15:F15 

Как бы избавиться от двоеточия для справки курса? Я хочу, чтобы это выглядело как этот

15S13

Мой код

struct studentinfo 
{ 
    string name; 
    string classref; 
}; 

void readNumbers(istream &input, char *argv[], int argc) 
{ 

    string program = argv[0]; 
    string text = argv[1]; 
    studentinfo array[10]; 
    string name; 
    int i=0; 

    if(text=="students.txt"){ 
     while(!getline(input, array[i].name, ':').eof()){ 
      input >> array[i].classref; 
      i++; 
    } 

    for(int j=0; j < i; j++){ 
     cout<< array[j].name << endl; 
    } 

    for(int i=0; i < 10; i++){ 
     cout << array[i].classref << endl; 
    }  
} 
+0

Это действительно зависит от шаблона использования, нет? Как часто вы делаете запросы относительно обновлений, какие запросы вы делаете и т. Д. В качестве крайнего примера, если вы почти никогда не запрашиваете и не обновляете, вы можете использовать вектор, к которому вы добавляете материал в конце. –

+0

Действительно, зависит от того, для чего вы хотите его сохранить - вы спрашиваете о сохранении или внутренней памяти? Ваш проект большой? Будете ли вы обновлять его чаще, чем запрос? У вас есть естественные ключи? –

+0

@Lauren Вы должны задать новые вопросы, а не редактировать существующие, чтобы полностью изменить то, что его спрашивают. Теперь вы полностью отдалились от контекста. Вы получите более высокий рейтинг, задав больше вопросов, поэтому в ваших интересах это сделать. –

ответ

2

Это является ответом на несколько итераций этого вопроса, так что это может показаться немного отстаёт от того, что спросил выше.


Проблема заключается в том, что вы используете std::getline прочитать до «:» характер. Затем вы используете перегруженный оператор >> для std::string, чтобы сделать еще одну запись в той же строке name, перезаписывая ее. На этот раз он читает до конца строки.

После вызова std::getline переменная name содержит John.Smith, а затем вы сразу же перезаписать это значение, выполнив input >> name;. Это, по сути, то же самое, что и getline, без возможности указания разделителя. Строка name затем содержит 11:F12, которую вы копируете в свой массив для последующего отображения.

Я думаю, что ваше замешательство в том, как были замечены работы getline, вам не нужно было читать значение имени, используя >>, он уже был в строке name. Вам просто нужно было прочитать остальную часть строки и отбросить ее. Я рекомендую вам прочитать онлайн-ссылку для std::getline, чтобы лучше понять, как она работает.

Чтобы устранить проблему, вы можете выполнить любое из следующих действий.

  1. ли еще «GetLine» или «>>» после того, как вы скопировали name в массив и отбросить значение, таким образом она очищает остальную часть линии, и вы затем прочитать следующее имя в вашем петельных getline вызов. Немного взломанный способ достижения этого - переместить input >> name; после строки, которая добавляет name к массиву.
  2. Прочитайте всю строку без разделителя, а затем найдите (используя функцию-член find) первое вхождение ':' и возьмите подстроку до этого символа (используя функцию-член substr).
  3. Определите структуру с именем & членов класса и прочитайте оба значения в структуре. Таким образом, вы намеренно читаете оба значения из файла. Если вам не нужна строка курса, это может быть излишним.

Некоторые коды, которые более или менее делают то, что я предлагаю.

#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>.

+0

Большое спасибо! – Lauren

Смежные вопросы