0 / 0 / 0
Регистрация: 30.07.2015
Сообщений: 11
1

Чтение CSV-файла в двумерный массив

30.07.2015, 01:52. Показов 8955. Ответов 8
Метки нет (Все метки)

Есть файл вида:
"TEXT,1,20140729,150700,73.350 0000,73.5800000,73.3500000,73. 4800000,2301260"
Нужно собрать числа в двумерный массив. Количество строк в файле неизвестно.
Попробовал использовать регулярные выражения. Но это очень долго. Есть способ побыстрее?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdafx.h"
#include <iostream>
#include <regex>
 
using namespace std;
 
int main(int argc, char** argv) {
  const char *filename = "R:\\data.csv";
  FILE* file;
  fopen_s (&file, filename, "rt");
  if (!file) cout << "File not found";  // Как сюда добавить имя файла?
  else {
    char line[100];
    cmatch res;
    while (!feof(file)) {
      fgets(line, 99, file);
      if (regex_search(line, res, regex("^[^,]+,\\d+,(\\d{8}),(\\d{6}),(\\d+\\.?\\d*),(\\d+\\.?\\d*),(\\d+\\.?\\d*),(\\d+\\.?\\d*),(\\d+)$"))) {
        // Преобразовать в числовой тип и добавить числа в двумерный массив
      }
    }
    fclose(file);
  }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.07.2015, 01:52
Ответы с готовыми решениями:

Чтение из csv файла в двумерный массив географических координат с нестандартными символами
Добрый вечер! После Hello Word это моя первая прога на с++, поэтому очень прошу помочь. Задача...

Чтение в двумерный массив из файла
Есть некоторая последовательность целых чисел, которая хранится в файле. Её нужно считать и...

Чтение csv файла в массив
подскажите пожалуйста как можно из одного массива сделать два. Есть csv фаил где храняться имена и...

Как записать значения из csv файла в двумерный массив?
Ситуация такова. Я новичок в C#. Как можно записать значения из csv файла в двумерный массив для...

8
Модератор
Эксперт С++
12062 / 9748 / 5896
Регистрация: 18.12.2011
Сообщений: 26,170
30.07.2015, 07:12 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//TEXT,1,20140729,150700,73.3500000,73.5800000,73.3500000,73.4800000,2301260
char txt[16]={0};
int k[4];
double a[4];
ifstream fin(filename);
do
{
  if( !fin.get(txt,15,',') )
       break;
  fin>>k[0]>>k[1]>>k[2];
  fin>>a[0]>>a[1]>>a[2]>>a[3];
  fin>>k[3];
  fin.get(); // пропуск \n
...
}while( true);
1
0 / 0 / 0
Регистрация: 30.07.2015
Сообщений: 11
30.07.2015, 13:56  [ТС] 3
Что-то не получается. В результате выполнения скрипта
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdafx.h"
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main(int argc, char** argv) {
  char txt[16]={0};
  int k[4];
  double a[4];
  ifstream fin("R:\\data.csv");
  int i = 0;
  do {
    if ( !fin.get(txt, 15, ',') ) break;
    fin>>k[0]>>k[1]>>k[2];
    fin>>a[0]>>a[1]>>a[2]>>a[3];
    fin>>k[3];
    fin.get(); // пропуск \n
    cout<<++i<<": "<<k[0]<<"; "<<k[1]<<"; "<<k[2]<<"; "<<a[0]<<"; "<<a[1]<<"; "<<a[2]<<"; "<<a[3]<<"; "<<k[3]<<endl;
  } while(true);
  system("pause");
}
я получаю только одну строку:
Код
1: -858993460; -858993460; -858993460; -9.25596e+061; -9.25596e+061; -9.25596e+061; -9.25596e+061; -858993460
Добавлено через 3 часа 42 минуты
Надо было разделители (запятые) ещё куда-то запихать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "stdafx.h"
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main(int argc, char** argv) {
  char txt[100], s;
  int k[4];
  double a[4];
  ifstream fin("R:\\data.csv");
  fin >> txt;  // Пропускаем первую строку
  do {
    if ( !fin.get(txt, 15, ',') ) break;
    fin>>s>>k[0]>>s>>k[1]>>s>>k[2];
    fin>>s>>a[0]>>s>>a[1]>>s>>a[2]>>s>>a[3];
    fin>>s>>k[3];
    fin.get(); // пропуск \n
  } while(!fin.eof());
  system("pause");
}
А как в двумерный массив записать (построчно), если не известно количество строк в файле?
0
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 177
30.07.2015, 14:15 4
Цитата Сообщение от CyberTrader Посмотреть сообщение
Есть файл вида:
Начнем с того, что файл такого вида вообще не подразумевает табличные данные, и восстановить таблицу из него ты не сможешь ( 2 х 4 равно 4 х 2, если предполагать это для 8и элементов в файле, разделенных "," ).
Как минимум файл должен содержать 2 управляющих символа (признак поля и признак конца строки).
Соответственно, пока не встретишь признак конца строки, читаешь данные в одну строку.

Добавлено через 2 минуты
У меня CSV файлы вообще, так выглядят:
CSVgigant,"0,5900"
earth,"0,3000"
dwarf,"0,1050"
asteroid,"0,0050"
0
В астрале
Эксперт С++
8042 / 4799 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.07.2015, 14:23 5
CyberTrader, Т.е. regex вы использовали, а вот vector не?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
 
int main()
{
   const std::string fname = "data.csv";
   std::ifstream ifs(fname.c_str());
   if (!ifs)
   {
      std::cerr << "No file with name: " << fname << std::endl;
      return 1;
   }
   std::vector<std::vector<double> > values;
   std::string line;
   while (ifs.good())
   {
      std::getline(ifs, line);
      std::replace(line.begin(), line.end(), ',',  ' ');
      std::stringstream ss(line);
      std::string current;
      std::vector<double> temp;
      while (ss >> current)
      {
         try
         {
            const double d = std::stod(current);
            temp.push_back(d);
         }
         catch (const std::exception& e)
         {
         }
      }
      values.push_back(temp);
   }
   ifs.close();
   for (const auto& vec : values)
   {
      for (const auto& v : vec)
      {
         std::cout << v << " ";
      }
      std::cout << std::endl;
   }
}
1
0 / 0 / 0
Регистрация: 30.07.2015
Сообщений: 11
30.07.2015, 22:47  [ТС] 6
Цитата Сообщение от ForEveR Посмотреть сообщение
CyberTrader, Т.е. regex вы использовали, а вот vector не?
Ну, как-то так, да.

Вот так-то побыстрее будет:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main() {
  const char *sFileName = "R:\\data.csv";
  vector<vector<double> > aData;
  vector<double> v;
  ifstream hFile (sFileName);
  if (!hFile) cout << "Не удалось открыть файл";
  else {
    char sLine[100], s;
    double d;
    hFile >> sLine;  // Пропускаем первую строку
    while (!hFile.eof()) {
      if ( !hFile.get(sLine, 15, ',') ) break;
      for ( size_t i=0; i<=7; i++ ) {
        hFile >> s >> d;
        v.push_back(d);
      }
      hFile.get();  // пропуск \n
      aData.push_back(v);
      v.clear();
    }
    hFile.close();
  }
  for ( size_t i=0; i<aData.size(); i++ ) {
    v = aData[i];
    for ( size_t j=0; j<v.size(); j++ ) {
      cout << v[j] << "; ";
    }
    cout << endl;
  }
}
А можно с помощью fgets сделать? Он быстрее файлы читает.
0
В астрале
Эксперт С++
8042 / 4799 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
31.07.2015, 10:44 7
CyberTrader, Да как хотите можете делать.)
0
0 / 0 / 0
Регистрация: 30.07.2015
Сообщений: 11
03.08.2015, 12:58  [ТС] 8
Если необходимо проверить, чтобы формат считываемых строк соответствовал требуемому, то это только с помощью regex можно сделать?

Добавлено через 1 час 8 минут
Пардон, не обратил внимания, что тут есть проверка:

C++
1
2
3
4
5
6
7
8
try
   {
     const double d = std::stod(current);
     temp.push_back(d);
   }
      catch (const std::exception& e)
   {
   }
Добавлено через 2 часа 35 минут
Не могли бы вы пояснить, что означает вот эта строка?
C++
1
while (ss >> current)
0
В астрале
Эксперт С++
8042 / 4799 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
03.08.2015, 14:28 9
CyberTrader, Оператор >> возвращает поток, который приводится к bool (void*) в контексте проверки.
http://en.cppreference.com/w/c... rator_bool
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.08.2015, 14:28
Помогаю со студенческими работами здесь

Чтение CSV-файла в массив. Поделитесь удачным опытом. Спасибо.
Не получается объявить массив равный количеству строк файла. Dim (17, LinesInFile) требует, чтобы...

Двумерный массив чтение из файла
Ребят, нужно крч в таблице прочитать файл. Вот я попытался сделать чтение, но чёт я не смог найти...

Чтение файла в динамический двумерный массив
Задача сама по себе простая , но как бы я не пытался заполнять ни по строчно через fgets ни по...

Двумерный массив запись/ чтение из файла
подскажите пожалуйста как считать из файла двумерный массив размера n´n, заполненный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru