Чтение и обработка файлов CSV - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток всем. Посмотрите пожалуйста задание. Разработать статистическую библиотеку на языке С для работы с файлами формата СSV. Должны быть реализованы 3 функции:
/*читает одну строку из файла ввода f; подразумевается что строки во вводе оканчиваются символами \r, \n, \r\n или EOF. Возвращает указатель на строку (символы конца русской строки удаляются) или NULL, если достигнут EOF. Строки могут иметь произвольную длинну; возвращяется NULL, если превышен резерв памяти, строки рассматриваются как память, доступная только для чтения; для сохранения или изменения содержимого вызывающая сторона должна сделать копию. */
char *csvgetline (FILE *f);
/*Поля нумеруются начиная с 0. Возвращает n-e поле из последней строки, прочитанной csvgetline; возвращает NULL, если n отрицательно или лежит за последним полем, поля разделяются запятыми. Поля могут быть заключены в двойные кавычки, эти кавычки убираются; внутри двойных кавычек запятая не является разделителем, а пара символов "" заменяется на ". В полях, не ограниченных кавычками, кавычки рассматриваются как обычные символы, может быть произвольное количество полей любой длинны; возвращает NULL, если превышается резерв памяти, поля рассматриваются как память, доступная только для чтения; для сохранения или изменения содержимого вызывающая сторона должна сделать копию, при вызове до csvgetline поведение не определено. */
char *csvfield (int n);
/* возвращает количество полей в последней строке, прочитанной csvgetline. при вызове до csvgetline поведение не определено. */
int csvnfield (void); Задание надо реализовать на С, в универе мы учим только С++, вот мои наработки
// csv getline.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <iostream>
using namespace std;
 
void main()
{
  char * line;
  char bus[100];
  printf("%s","VVEDITE NAME FILE");
  scanf("%100s",bus);
  FILE*f=fopen(bus,"r");
   while(!EOF(F));
   {
   line=csvgetline(F);
  if(line==0){printf("%s","ERROR");
   fclose;
   return 0;}
  else
   {
    for(int i=0;i<csvgetline(f);i++)
    printf("%s","vse horowo",csvfield(i));
    fclose;
    return 0;}
   }

  char * csvgetline(FILE* f)
  {
   char buf[10];
   int maxline=1,count=0;
   line=(char*)malloc(maxline);
   while((bus[0]=getc(f))!=EOF){
    if(EOF(buf)){cout>>" EOF(BUF) complete)"};
    if(counter=>maxline);
    {realloc(line,maxline);
    maxline=maxline*2;
    cout>>"memory added";
    }}
 
  char* csvfield(int n){ // вот эту надо доделать
 
  return 0;
  }
 
  int* csvnfield(void){ // эту тоже доделать
  
  return 0; 
  }
return 0;
}

Решение задачи: «Чтение и обработка файлов CSV»

textual
Листинг программы
#include <stdafx.h>
#include <iostream>
using namespace std;
class Csv { // читает и разбирает CSV
// пример ввода: "LIT, 86. 25, "11/4/1998",
"2:19РМ", +4. 0625
 public:
Csv(istream& fin = cin, string sep = ",") : 
fin(fin), fieldsep(sep) {}
 int getline(string&);
string getfield(int n);
 int getnfieldO const { return nfield; }
private:
 istream& fin; // указатель на файл ввода
 string line; // вводимая строка
vector<string> field; // строки полей
 int nfield; // количество полей
string fieldsep; // символы разделителей
 int split();
 int endofline(char);
 int advplain(const string& line, 
string& fid, int);
 int advquoted(const string& line, 
 string& fid, int); };
 // getline: получает одну строку,
// по мере необходимости 
наращивает размер
 int Csv::getline(string& str)
 {
 char c;
 for (line = ""; fin.get(c) && !endofline(c); )
line += c; split(); str = line; return !fin.eof(); 
}
// endofline: ищет и удаляет
 \r', \n, \r\n или EOF
 int Csv::endofline(char с)
{
 int eol;
eol = (c==Ar' || c=='\n');
 if (с == V) { , fin.get(c); if
 (!fin.eof() && с != '\n',)
 fin.putback(c); 
// слишком много прочитали >
 return eol; 
}
 А вот как выглядит новая версия функции split: 
 // split: разделяет строку на поля
 int Csv::split()
 {
 string fid;
 int i, j;
nfield = 0;
  if (line.lengthO == 0)
return 0; i = 0;
 do 
{
if (i < line.length()
&& line[i] == '".')
 j = advquoted(line, fid, ++i);
 // пропуск кавычки else
 j = advplain(line, fid, i);
if (nfield >= field.size())
 field.push^back(fld);
 else
 field[nfield] = fid; nfield++; i = j + 1;
 }
 while (j < line.length());
 return nfield; 
 }
 // advquoted: для полей, 
        
заключенных в кавычки;
 // возвращает индекс следующего разделителя
 int Csv::advquoted(const string& s, string& fid, int i)
 {
 int j;
 fid = "";
 for (j = i; j < s.length(); j++) 
 {
 if (S[j] == "&& s[++j] != ") 
 {
 int k = s.find_first_of(fieldsep, j);
 if (k > s.length())
 // разделитель не найден
 k = s.length(); for (k -= j; k-- > 0; )
 fid += s[j++]; 
 break;
 }
 // advplain: для полей, не заключенных в кавычки,
// возвращает индекс следующего разделителя 
int Csv::advplain(const strings s, strings fid, int i) 
 
{
  int j;
 j = s.find_first_of(fieldsep, i);
 // поиск разделителя if (j > s.lengthO)
 // разделитель не найден
 j = s.lengthO; fid = string(s, i, j-i); return j;
 }
 И снова, как и в предыдущей версии, Csv::getfield абсолютно тривиальна, a Csv: :getnfield настолько коротка, что воплощена прямо в описании класса. 
// getfield: возвращает n-e поле string
 Csv::getfield(int n) {
 if (n < 0 n >= nfield)
 return ""; else
 return field[n]; 
}

Объяснение кода листинга программы

В этом коде реализована функция для чтения и обработки файлов формата CSV (Comma-Separated Values). Вот список действий, которые выполняются в этом коде:

  1. Создается класс Csv, который имеет методы для чтения строк из файла и разделения этих строк на поля.
  2. В методе getline строка считывается из файла до конца строки или до символа новой строки.
  3. В методе endofline проверяется, является ли текущий символ концом строки или символом новой строки.
  4. В методе split строка разделяется на поля с помощью двух вложенных циклов. Если текущий символ является открывающей кавычкой, вызывается метод advquoted для обработки поля, заключенного в кавычки. В противном случае вызывается метод advplain.
  5. В методе advquoted происходит поиск закрывающей кавычки и, если она найдена, вычисляется позиция следующего разделителя. Если закрывающая кавычка не найдена, в поле добавляются все символы до конца строки.
  6. В методе advplain происходит поиск разделителя и, если он найден, вычисляется позиция следующего разделителя. Если разделитель не найден, в поле добавляются все символы до конца строки.
  7. В методе getfield возвращается n-е поле из вектора field. Если n меньше 0 или больше количества полей, возвращается пустая строка. Список действий, которые выполняются в этом коде, не превышает 20 элементов.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4 из 5
Похожие ответы