Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с текстовым фалом в формате csv и xml 
:(
    Опции темы
Moby
Дата 30.8.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Задача: Есть два файла один текстовой и один формата xml. В каждом хранится много информации в основном численной. Что мне с ними делать надо будет не столь важно, а важно получить внутреннее представление этих фалов, ну там в массив все загнать или еще что нибудь.

Для начала вот как выглядит текстовой файл в формате csv.

xx,xxxxxxxxxxxxxxx;xx,xxxxxxxxxxxxxxx;dd.mm.yyyy hh:mm:ss

где x = 0...9, то есть любое число, а дальше это дата и время.

И само собой таких записей много, то есть

xx,xxxxxxxxxxxxxxx;xx,xxxxxxxxxxxxxxx;dd.mm.yyyy hh:mm:ss
xx,xxxxxxxxxxxxxxx;xx,xxxxxxxxxxxxxxx;dd.mm.yyyy hh:mm:ss
.
.
.
.
.
.
.
xx,xxxxxxxxxxxxxxx;xx,xxxxxxxxxxxxxxx;dd.mm.yyyy hh:mm:ss


Вопрос: Как мне лучше представить эти данные? Создать 4х мерный массив? Или есть более удобное представление? И как бы то ни было ведь нужно будет использовать файловый ввод-вывод, желательно С++ а не С. И что именно использовать.

Я не прошу Вас о полном ответе, мне хватит и общих наставлений. Ну может быть есть удобные структуры хранения таких данных в STL и может быть очень удобная функция типа fseek() что бы легко отделить дату от первых двух значений.

Заранее спасибо. 

PM MAIL ICQ   Вверх
kosmonaFFFt
Дата 30.8.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5





--------------------
user posted image
PM MAIL ICQ   Вверх
Moby
Дата 30.8.2010, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Спасибо. Но для меня, учитывая сроки, тяжко разобраться как это использовать, да и хотелось бы самому.

Как мне используя fstream раскидать по массиву вот такой текстовый файл
10;20;30
40;50;60 


что бы i[0][0] = 10, i[1][0] = 20.....

ifstream in;
in.open("test.txt");

а дальше что делать? 


PM MAIL ICQ   Вверх
djamshud
Дата 30.8.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Вам не кажется, что это руками пишется за две минуты?


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Moby
Дата 30.8.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Смотря какие руки. smile
Я никогда не работал с вводом\выводом текстовых файлов и никогда не использовал fstream. Конечно сейчас я читаю, смотрю примеры и постепенно учусь, но если бы кто-то написал хоть что нибудь, то хуже бы не стало. Я же не спрашиваю а как сделать так, что бы консоль не закрывалась. smile

PM MAIL ICQ   Вверх
bsa
Дата 30.8.2010, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Moby, тебе нужна структура, состоящая из 3-х полей:
Код
struct MyData
{
   long double x;
   long double y;
   time_t date;
   MyData(); //создает пустую структуру
   explicit MyData(const std::string &line); //парсит строку
};

std::vector<MyData> array;

PM   Вверх
jonie
Дата 30.8.2010, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



bsa, тебе не кажется что использование констроров тут излишне ? Мне кажется что стоит использовать operator<< , нежели конструкторы .. да и нагляднее имхо.
Хотя с другой стороны имея implicit конструктор из строки в данные можно использовать :
Код

vector<RowData> rows;
std::copy(std::istream_iterator<string>(input), std::istream_iterator<string>(), std::back_inserter(rows));


Это сообщение отредактировал(а) jonie - 30.8.2010, 19:32


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
ИванМ
Дата 30.8.2010, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(Moby @  30.8.2010,  15:08 Найти цитируемый пост)
Как мне используя fstream раскидать по массиву вот такой текстовый файл
10;20;30
40;50;60 
что бы i[0][0] = 10, i[1][0] = 20.....

Если только из трех столбцов состоит файл и i - си-строка, то можно два раза вызвать getline с символом-разделителем ';' и один раз с '\n'. Типа такого:
Код

for(size_t j=0;!in.eof();j++)
{
in.getline(i[0][j], максимальная_длина, ';');
in.getline(i[1][j], максимальная_длина, ';');
in.getline(i[2][j], максимальная_длина, '\n');


Если i - int:
Код

for(size_t j=0;!in.eof();j++)
for(size_t k=0;k<3;k++)
{
    in>>i[k][j];
    in.get();
}


Это сообщение отредактировал(а) ИванМ - 30.8.2010, 21:07
PM MAIL   Вверх
Moby
Дата 30.8.2010, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Спасибо за ответы. Только прочел их, а до этого все таки сидел и сам пытался разобраться. Многое сделано тупо и в лоб. Посмотрите и прокомментируйте, что мне переписать "по человечески".


Использовал два потока. Один что бы посчитать кол-во строк. Зачем? Потому что после вот такого условия
Код

 while(!in1.eof())
    {
        rows++;
        getline(in1, str);
    }
 не знаю как вернуться к первой строке. smile

Но самое главное это то, что в текстовом файле лежит значение 55,6685371398926 а в массив попадает урезанная 55.6685. То есть 4-е знака после запятой. Как тут быть? 
Так же прошу заметить тупой способ борьбы с запятой. Значения в тексте используют разделитель не точку, а запятую. Я сперва беру все значение как стринг и разбиваю уже его на до запятой и после и складываю со знаком точка и только потом перевожу в флоат. Весьма тупо, не правда ли. smile
А вот код.

Код


#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{


    string str1,str2,str;
    fstream in, in1;
    int pos, pos2, rows = 0;
    float f;
    stringstream ss;
    cout << "Please, enter full path to file" << endl;

    in.open("test.txt");
    in1.open("test.txt");
    
    while(!in1.eof())
    {
        rows++;
        getline(in1, str);
    }
    str.clear();
    in1.close();
    rows-=1;
    
    float** matrix = new float*[rows];
    for (int i = 0; i <= rows; ++i)
        matrix[i] = new float[3];

    for (int i = 0; i < rows; ++i)
    {
        getline(in, str1);
        cout << str1 << endl;

        for(int j = 0; j < 2; j++)
        {
            pos = str1.find(";");
            
            str2.assign(str1, 0, pos);
            pos2 = str2.find(",");
            str.assign(str2, pos2+1, str2.size());
            str2.assign(str2,0,pos2);
            str2=str2+"."+str;
            ss << str2;
            ss >> f;
            ss.clear();
            matrix[i][j] = f;
            str1.assign(str1, pos+1, str1.size());
        }
    }
    cout << endl;

    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j <2; j++)
        {
            cout << matrix[i][j]<< ";";
        }
        cout << endl;
    }
    

    system("pause");
    return 0;
}


 

Это сообщение отредактировал(а) Moby - 30.8.2010, 22:56
PM MAIL ICQ   Вверх
ИванМ
Дата 30.8.2010, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(Moby @  30.8.2010,  22:54 Найти цитируемый пост)
Использовал два потока. Один что бы посчитать кол-во строк. Зачем? Потому что после вот такого условия
 while(!in1.eof())
    {
        rows++;
        getline(in1, str);
    }
 не знаю как вернуться к первой строке. smile

Вообще ничего не понял. Причем тут подсчет строк и первая строка и как это связано с потоками. В вашем коде ни одного второго потока не нашел.

Цитата(Moby @  30.8.2010,  22:54 Найти цитируемый пост)
Но самое главное это то, что в текстовом файле лежит значение 55,6685371398926 а в массив попадает урезанная 55.6685. То есть 4-е знака после запятой. Как тут быть? 

Хранить в double и при выводе использовать нужные флаги. Пример:
Код

double d=55.6685371398926;
cout<<fixed<<setprecision(13)<<d<<endl;


Цитата(Moby @  30.8.2010,  22:54 Найти цитируемый пост)
Так же прошу заметить тупой способ борьбы с запятой. Значения в тексте используют разделитель не точку, а запятую. Я сперва беру все значение как стринг и разбиваю уже его на до запятой и после и складываю со знаком точка и только потом перевожу в флоат. Весьма тупо, не правда ли. 

Для таких целей существует локаль ( setlocale(...) ).

Цитата(Moby @  30.8.2010,  22:54 Найти цитируемый пост)
Посмотрите и прокомментируйте, что мне переписать "по человечески".

Чтобы было по-человечески придется переписать весь код. Почитайте, что вам рекомендовали про классы (хотя для такого случая можно и без них). Забудьте про динамические массивы, используйте контейнеры. Тогда вам вообще не придется подсчитывать число строк.

Это сообщение отредактировал(а) ИванМ - 30.8.2010, 23:25
PM MAIL   Вверх
jonie
Дата 31.8.2010, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Код

using namespace std;

class RowData
{
    long double x;
    long double y;
    string date;

    //RowData& operator=(const RowData str);
public:
    friend istream& operator>>(istream& is, RowData& rhs);
    RowData()
    {
    }

    RowData(string s)
    {
        istringstream is(s);
        is>>*this;
    }
};

istream& operator>>(istream& is, RowData& rhs)
{
    is>>rhs.x;
    is.get();
    is>>rhs.y;
    is.get();
//.... парсинг даты...
    return is;
}


//где-то в main
    std::locale loc ("German_Germany");
    std::locale::global(loc);  //плохой код)

    ifstream input("C:\\test.data", fstream::in);
    
    vector<RowData> rows;
    std::copy(std::istream_iterator<string>(input), std::istream_iterator<string>(), std::back_inserter(rows));



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Moby
Дата 31.8.2010, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Цитата(ИванМ @ 30.8.2010,  23:11)
Цитата(Moby @  30.8.2010,  22:54 Найти цитируемый пост)
Использовал два потока. Один что бы посчитать кол-во строк. Зачем? Потому что после вот такого условия
 while(!in1.eof())
    {
        rows++;
        getline(in1, str);
    }
 не знаю как вернуться к первой строке. smile

Вообще ничего не понял. Причем тут подсчет строк и первая строка и как это связано с потоками. В вашем коде ни одного второго потока не нашел.

Я неправильно обозвал это, я имел ввиду что создал два  fstream .

Но я так и не понял как можно после подсчета строк таким образом вернуться на первую?

jonie, спасибо. Выглядит очень просто, кое что непонятно, но буду разбираться.
PM MAIL ICQ   Вверх
ИванМ
Дата 31.8.2010, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(Moby @  31.8.2010,  13:51 Найти цитируемый пост)
Но я так и не понял как можно после подсчета строк таким образом вернуться на первую?

Никак. Просто не нужно делать подсчет строк.

jonie, я бы использовал list, а не vector, с остальным согласен.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1492 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.