split — Извлечение данных CSV из столбца x в столбец y и из строки 1 в строку 2 Переполнение стека

У меня есть файл .csv, скажем, 1000 строк и 1200 столбцов.

Как извлечь данные из нужного столбца, скажем 67, в другой столбец, скажем 890.
И в то же время из ряда, скажем 9, в другой ряд, скажем 789, затем экспортировать данные как новый CSV-файл с C ++?

Я все еще новичок, но знаком с циклом for или while, и я могу прочитать файл.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;int main() {

ifstream csvFile;

csvFile.open("../example.csv");

if (csvFile.is_open())
{

string line;

while(getline(csvFile, line))
{

//what to do here

}
}

else {

cout << "Sorry, the file could not be openend." <<endl;

return -1;

}

csvFile.close();

return 0;

}

редактировать
например исходный CSV-файл:

a,1,11,111
b,2,22,222
c,3,33,333
d,4,44,444

допустим, мы хотим только из столбца 2 в столбец 3 и из строки 2 в 3, тогда результатом будет новый CSV-файл, подобный этому:

2,22
3,33

0

Решение

Есть несколько способов сделать это. Первое, что приходит на ум, это читать ваши .csv файл в вектор vector<string> так что каждое значение строки / столбца сохраняется в двумерном массиве, подобном векторному контейнеру векторов. (например. std::vector<std::vector<string>> array;). Это позволяет вам легко разбирать ваши .csv использование файла getline и stringstream в строке читать (разделены на ',').

Затем вы могли бы написать функцию извлечения, которая берет ссылку на ваши сохраненные значения csv и выполняет итерацию по векторам, используя основанный на диапазоне итератор как для отдельных векторов, так и для строк. На этом этапе нужно просто сохранить индекс строки и столбца и вывести все значения строки между желаемым диапазоном и столбцом в пределах желаемого диапазона. Простая функция будет выглядеть так:

 void extract (vector<vector<string>>const & array, size_t r1, size_t c1,
size_t r2, size_t c2)
{
size_t ridx = 0;                    /* row index */
for (auto& row : array) {           /* range based row iterator */
size_t cidx = 0;                /* column index */
if (r1 <= ridx && ridx <= r2) { /* if in row range */
for (auto& col : row) {     /* range based col iterator */
if (c1 <= cidx && cidx <= c2) { /* if in col range */
if (cidx > c1)      /* if greater than 1st */
cout << ",";    /* output separator */
cout << col;        /* output value */
}
cidx++;                 /* increment col index */
}
cout << "\n";               /* output newline */
}
ridx++;                         /* increment row index */
if (ridx > r2)                  /* break if row > r2 */
break;
}
}

Вы можете создать вторичный вектор строк для возврата для дальнейшей обработки или просто вывести значения (или записать в другой файл), как это было сделано выше.

Собрав воедино кусочки в коротком примере, который читает ваш CSV-файл, выводя строки между строкой 1, столбцом 1 и строкой 2 и столбцом 2, как показано в вашем вопросе, вы можете сделать что-то вроде следующего:

#include <iostream>
#include <fstream>
#include <sstream>

#include <string>
#include <vector>

using std::ifstream;
using std::cout;
using std::cerr;
using std::string;
using std::stringstream;
using std::vector;

void extract (vector<vector<string>>const & array, size_t r1, size_t c1,
size_t r2, size_t c2)
{
size_t ridx = 0;                    /* row index */
for (auto& row : array) {           /* range based row iterator */
size_t cidx = 0;                /* column index */
if (r1 <= ridx && ridx <= r2) { /* if in row range */
for (auto& col : row) {     /* range based col iterator */
if (c1 <= cidx && cidx <= c2) { /* if in col range */
if (cidx > c1)      /* if greater than 1st */
cout << ",";    /* output separator */
cout << col;        /* output value */
}
cidx++;                 /* increment col index */
}
cout << "\n";               /* output newline */
}
ridx++;                         /* increment row index */
if (ridx > r2)                  /* break if row > r2 */
break;
}
}

int main (int argc, char **argv) {

string line;
vector<vector<string>> array;

if (argc < 2) {
cerr << "error: insufficient input.\n""usage: " << argv[0] << " filename\n";
return 1;
}

ifstream f (argv[1]);   /* open file */
if (!f.is_open()) {
perror (("error while opening file " + string(argv[1])).c_str());
return 1;
}

while (getline (f, line)) {         /* read each line */
string val;                     /* string to hold value */
vector<string> row;             /* vector for row of values */
stringstream s (line);          /* stringstream to parse csv */
while (getline (s, val, ','))   /* for each value */
row.push_back (val);        /* add to row */
array.push_back (row);          /* add row to array */
}
f.close();

cout << "complete array\n\n";
for (auto& row : array) {           /* iterate over rows */
for (auto& val : row)           /* iterate over vals */
cout << val << "  ";        /* output value      */
cout << "\n";                   /* tidy up with '\n' */
}

cout << "\nextracted array\n\n";
extract (array, 1, 1, 2, 2);        /* extract from 1,1 to 2,2 */

return 0;
}

(нота: основанный на диапазоне цикл является функцией C ++ 11, поэтому добавьте -std=c++11 к вашей строке компиляции)

Вам не нужно читать весь файл в хранилище. Вы можете так же легко сохранить количество строк и столбцов во время первоначального чтения строк и анализа столбцов с помощью stringstream и только заполнить array со значениями, которые вы хотите вывести, или просто вывести значения в это время, но путем инкапсуляции extract подпрограмма в функции, вы можете работать с любым количеством диапазонов вашего CSV-файла, как вам нравится. Это полностью зависит от вас. Полное чтение дает вам возможность вывести столько разных частей вашего файла, сколько вам нужно, без необходимости выполнять ввод-вывод более одного раза в исходном файле.

Пример использования / Вывод

$ ./bin/iostream_sstream_csv dat/extract.csv
complete array

a  1  11  111
b  2  22  222
c  3  33  333
d  4  44  444

extracted array

2,22
3,33

Вероятно, в C ++ существует больше способов заключить в скобки требуемые индексы строк и столбцов, чем хранить простые индексы строк и столбцов, но это работает каждый раз. Вы можете посмотреть в distance() или вычитая текущий итератор из вашего вектора.begin(), но есть ограничения, к которым применяются итераторы. Старые добрые индексы не волнуют.

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0

Другие решения

Я предполагаю, что главный вопрос в том, чтобы поймать данные / переменную из данного столбца / строки:
1. нужно определить «диапазон» и его

2 взять данные с помощью «value2 ()»

Что касается внешнего вида, он просто не может быть «одновременно»: вы должны решить цель программы. Спасибо!

Мне очень жаль, но я не совсем использовал эту вставку кода, поэтому я поставил изображение:

введите описание изображения здесь

0

По вопросам рекламы [email protected]