Как обработать файл с пустыми строками?

186
05 апреля 2017, 16:38

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

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cassert>
using namespace std;
struct Team
{
    string name;
    string result;
    int point;
};
void Delete_Empty_Line ();
int  input_count();
void sort(Team * ,int);
Team* input(int);
void out(Team * ptr, int count);
int main(int argc, char *argv[])
{
    Delete_Empty_Line ();
    int count = input_count();
    Team * ptr = input(count);
    sort(ptr, count);
    out(ptr, count);
    return 0;
}
void Delete_Empty_Line (void)
{
    ifstream FileInput ("premier_league.csv", ifstream::in);
    ofstream FileOutput ("premier_league1.csv", ofstream::out);
    assert(FileInput);
    assert(FileOutput);
    string String_Of_File;
    while (FileInput)
    {
        getline(FileInput, String_Of_File);
        if (!String_Of_File.empty())
        {
            FileOutput << String_Of_File;
            FileOutput << endl;
        }   
    }
    FileInput.close();
    FileOutput.close();
}
int input_count()
{
    int lines = 0;
    char s;
    FILE *fp = fopen("premier_league1.csv","r");
    while((s=getc(fp))!=EOF)
    {        
        if(s == '\n')
        lines++;
    }
    fclose(fp);
    return lines;    
}
Team* input(int count)
{
    ifstream f("premier_league1.csv");
    int* a =new int ;
    char*  b =new char ;
    f >> *a;f >>*b;
    Team *ptr = new Team[count];
    for(int i = 0; i < count; ++i)
    {
        ptr[i].point = 0;
        getline(f,ptr[i].name, ',');
        getline(f,ptr[i].result, '\n');
    }
    delete a; delete b;
    return ptr;
}
void sort(Team * ptr,int count)
{
    int match = 10;
    for(int i = 0; i < count; ++i)
    {
        for(int j = 0; j < 40 ; j += 4)
        {
            if((int)ptr[i].result[j] > (int)ptr[i].result[j+2])
                ptr[i].point += 3;
            else if((int)ptr[i].result[j] == (int)ptr[i].result[j+2])
                ++ptr[i].point;
        }
    }
    for(int i = 0 ; i < count -1 ; i++ )
    {
        for( int j = 0; j < count-i-1; j++)
        {
            if( ptr[j].point < ptr[j+1].point)
            {
                Team temp = ptr[j+1];
                ptr[j+1] = ptr[j];
                ptr[j] = temp;
            }
        }
    }
 }
 void out(Team * ptr, int count)
 {
    ofstream fout;
    fout.open("results.csv", ios_base::out);
    for (int g = 0; g < count; g++)
     {
        fout << ptr[g].name << "," <<ptr[g].point << endl;
     }
    fout.close();
}
Answer 1

Не понимаю, зачем вам вообще int input_count(), если посчитать число строк можно и в input?

Тем более что вы делаете что-то странное - считаете количество строк, затем считываете значение a из первой строки, создаете массив из a элементов, но читаете туда их count штук. Если у вас в первой строке точное число строк - то зачем маета с input_count вообще? Если нет - вы уверены, что a больше количества строк?

Update
Вобщем, я бы делал так:

struct Team
{
    string name;
    string result;
    int point;
    void getPoint();
};
void Team::getPoint()
{
    point = 0;
    string s = result;
    istringstream is(s);
    int me, other;
    char c;
    while(is >> me >> c >> other >> c)
    {
        point += (me > other);
    }
};
vector<Team> readFile(istream&in)
{
    vector<Team> tt;
    string s;
    getline(in,s);
    while(getline(in,s))
    {
        if (s.empty()) continue;
        size_t comma = s.find(',');
        assert(comma != string::npos);
        Team t;
        t.name = s.substr(0,comma-1);
        t.result = s.substr(comma+1);
        t.getPoint();
        tt.push_back(t);
    }
    return tt;
}
int main(int argc, char *argv[])
{
    ifstream in("premier_league.csv");
    vector<Team> t = readFile(in);
    sort(t.begin(),t.end(),[](const Team& a, const Team& b){ return a.point > b.point; });
    ofstream out("premier_league.csv.new");
    out << t.size() << "\n";
    for(const auto& x: t)
    {
        cout << x.name << "," << x.result << "\n";
        out << x.name << "," << x.result << "\n";
    }
}
READ ALSO
В чем ошибка C++ код [требует правки]

В чем ошибка C++ код [требует правки]

Задание - В цикле с предусловием пользователем вводятся числа до тех пор, пока их сумма не превысит 100Определить количество введенных четных...

206
Файловый ввод-вывод объектов класса

Файловый ввод-вывод объектов класса

Доброго времени сутокЕсть класс, есть менюшка для работы с классом (добавление, вывод объектов класса, удаление) Каким образом организовать...

211
Поочерёдное открытие окон в Qt

Поочерёдное открытие окон в Qt

Например, есть QMainWindow, где находится форма входа (логин, пароль)При нажатии открывается еще один QMainWindow, уже сама программа, а старое окно закрывается...

295
Как передать в функцию массив, который хранится в обьекте

Как передать в функцию массив, который хранится в обьекте

У меня в объекте класса хранится инициализированный массивТеперь нужно в отдельной функции сделать манипуляции с этим массивом, но мне его...

178