Подсчет нет. слов в файле csv в c ++ - PullRequest
1 голос
/ 21 апреля 2020

Я пытаюсь сосчитать нет. хранилищ дат в первой строке файла CSV (разделенных запятыми): - State, Region, Lat, Long, 1/22 / 20,1 / 23 / 20,1 / 24 / 20,1 / 25/20, 26.01.20 Я должен считать нет. дат после Long (т. е. output = 5). Я написал код для чтения файла CSV, который я показал ниже, но как мне считать нет. дат после долгого. Буду очень признателен за вашу помощь. Пожалуйста, не стесняйтесь спрашивать любую другую информацию. Спасибо.

char** readCSV(const char* csvFileName, int& csvLineCount)
{
    ifstream fin(csvFileName);
    if (!fin)
    {
        return nullptr;
    }
    csvLineCount = 0;
    char line[1024];
    while(fin.getline(line, 1024))
    {
        csvLineCount++;
    };
    char **lines = new char*[csvLineCount];
    fin.clear();
    fin.seekg(0, ios::beg);
    for (int i=0; i<csvLineCount; i++)
    {
        fin.getline(line, 1024);
        lines[i] = new char[strlen(line)+1];
        strcpy(lines[i], line);
    };
    fin.close();
    return lines;
}

1 Ответ

1 голос
/ 21 апреля 2020

Похоже, что вы читаете запись, которая содержит одну или несколько подзаписей.
Я рекомендую использовать класс Date, а также класс Record.

class Date
{
  public:
    unsigned int month_num;
    unsigned int day_num;
    unsigned int year_num;

    friend std::istream& operator>>(std::istream& input, Date& d);
};

std::istream& operator>>(std::istream& input, Date& d)
{
    char forward_slash;
    input >> d.month_num;  input >> forward_slash;
    input >> d.day_num;    input >> forward_slash;
    input >> d.year_num;
    return input;
}

Перегрузка operator>> для класса Date пригодится позже.

Теперь класс записи:

class Record
{
  public:
    std::string    state;
    std::string    region;
    std::string    latitude;
    std::string    longitude;
    // A container for the date subrecords
    std::vector<Date> dates;

    friend std::istream& operator>>(std::istream& input, Record& r);
};

std::istream& operator>>(std::istream& input, Record& r)
{
     std::string text_line;
     std::getline(input, text_line);
     std::istringstream record_stream(text_line);
     std::getline(record_stream, r.state, ',');
     std::getline(record_stream, r.region, ',');
     std::getline(record_stream, r.latitude, ',');
     std::getline(record_stream, r.longitude, ',');
     Date d;
     while (record_stream >> d)
     {
         r.dates.push_back(d);
         char comma;
         record_stream >> comma;
     }
     return input;
}

Вышеуказанная функция читает текстовую строку ввода, так как записи завершаются переводом строки. Поток создается из текстовой строки. Поток помогает в чтении переменного количества дат.

Редактировать 1: чтение в файле
Ваш входной код будет выглядеть примерно так:

std::vector<Record> database;
Record r;
while (fin >> r)
{
    database.push_back(r);
}

Да, вы можете используйте C -строки и массивы, но потоки C ++ и std::vector упрощают код, и простой код имеет меньше дефектов, чем сложный код.

Кроме того, классы std::vector и std::string управляют динамической c памятью для вас. Они расширяются по мере необходимости. Нет необходимости проверять переполнение массива. Их также легче пройти. Передача массивов также требует пропускной способности (и, возможно, количества элементов в массиве).

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