Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Считывание численных данных из txt файла 
:(
    Опции темы
chaoss
Дата 27.8.2009, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Имеется текстовый файл (.txt), в котором записаны табличные численные данные. Данные разделены внутри строки tab-ми и, соответственно переходом на новую строку. Данные могут быть как целыми, так и дробями (разделяемые точкой или запятой, не суть важно).
Нужно, чтобы программа, написанная на Visual C++, могла взять такой txt файл и считать от туда все численные данные.

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

Решая эту проблему, я написал некоторый алгоритм, но, честно говоря, его работой не очень доволен. Работает, но приходится представлять данные в другом виде, более удобном для программы, но не удобном для чтения, встречаются неприятные исключения, одним словом, криво работает.

Наверняка, у такой распространенной задачи существует на много более простое решение. Буду благодарен за помощь. smile
PM   Вверх
andrew_121
Дата 28.8.2009, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Наверное правильней было бы вопрос тут задать: http://forum.vingrad.ru/forum/forum-471.html

Вот. Работает.
Код

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

typedef std::vector<std::string> line_type;
typedef std::vector<line_type> table_type;

/***************************************************************************/

line_type split(const std::string& str, std::string::value_type c) {
    line_type final;
    int j = 0;
    int i = str.find(c, j);
    int l = str.length();

    while ( i != -1 ) {
        if ( i > j && i <= l )
            final.push_back(str.substr(j, i - j));
        j = i + 1;
        i = str.find(c, j);
    }

    if ( str.substr(j, l-j+1).length() > 0 )
        final.push_back(str.substr(j, l-j+1));

    return final;
}

int main(int argc, const char** argv) {
    std::string temp;
    line_type line;
    table_type table;
    
    std::ifstream file("file.txt");
    if ( !file ) return 1;
    
    while ( !file.eof() ) {
        std::getline(file, temp);
        if ( temp.empty() ) continue;
        line = split(temp, '\t');
        table.push_back(line);
    }
    
    /** выводим в консоль */
    table_type::iterator str_it = table.begin();
    for ( ; str_it != table.end(); str_it++ ) {
        line_type::iterator line_it = str_it->begin();
        for ( ; line_it != str_it->end(); line_it++ ) {
            std::cout << *line_it << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    
    return 0;
}

/***************************************************************************/



Это сообщение отредактировал(а) andrew_121 - 28.8.2009, 00:41


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
andrew_121
Дата 28.8.2009, 02:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Немного поразмыслив, дополнил первый вариант классом variant
Это позволит приводить хранимые в файле значения, к нескольким типам, таким как: int, long long(тобишь __int64), double, std::string
Код

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

class variant;

typedef std::vector<variant> line_type;
typedef std::vector<line_type> table_type;

/***************************************************************************/

class variant {
public:
    variant(const std::string& s):str(s) {}
    variant(const variant& v):str(v.str) {}
    ~variant() {}
    /**  */
    int             to_int()        const { return atoi(str.c_str()); }
    double      to_double() const { return (double)atof(str.c_str()); }
    long long   to_int64()    const { return (long long)atof(str.c_str()); }
    std::string to_string()   const { return str; }
    /**  */
    operator int()                const { return atoi(str.c_str()); }
    operator std::string()    const { return str; }
private:
    variant();
    std::string str;
};

/***************************************************************************/

line_type split(const std::string& str, std::string::value_type c) {
    line_type final;
    int j = 0;
    int i = str.find(c);
    int l = str.length();

    while ( i != std::string::npos ) {
        if ( i > j && i <= l )
            final.push_back(str.substr(j, i - j));
        j = i + 1;
        i = str.find(c, j);
    }

    if ( str.substr(j, l-j+1).length() > 0 )
        final.push_back(str.substr(j, l-j+1));

    return final;
}

int main(int argc, const char** argv) {
    std::string temp;
    line_type line;
    table_type table;
    
    std::ifstream file("file.txt");
    if ( !file ) return 1;
    
    while ( !file.eof() ) {
        std::getline(file, temp);
        if ( temp.empty() ) continue;
        line = split(temp, '\t');
        table.push_back(line);
    }
    
    int iv = table[0][1].to_int();
    double dv = table[0][5].to_double();
    
    /** выводим в консоль */
    table_type::iterator str_it = table.begin();
    for ( ; str_it != table.end(); str_it++ ) {
        line_type::iterator line_it = str_it->begin();
        for ( ; line_it != str_it->end(); line_it++ ) {
            std::cout << *line_it << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    
    return 0;
}

/***************************************************************************/


Добавлено @ 02:52
Вот файл на котором тестировал:
Код

1    2    34    65    2.12    4.3
9.01    32.71    4    6    76    91


Добавлено @ 02:53
Как и требовалось, значения разделены табом('\t')

Это сообщение отредактировал(а) andrew_121 - 28.8.2009, 18:38


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
chaoss
Дата 28.8.2009, 03:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Большое спасибо!
Буду разбираться с кодом и вставлять в свою программу.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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