Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2011, 10:06   #1
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию Чтение таблицы из файла

возникла такая проблемка:
имеем файл, в котором есть неизвестное количество строк и в каждой строке некое количество чисел с плавающей точкой, причем в каждой строке количество чисел одинаково.
например такой файл:

1. 2. 3.
2. 3. 4.
3. 4. 5.
4. 5. 6.
6. 7. 8.

то есть 5 строк и по 3 числа в каждой строке.
как прочитать файл в таком формате и узнать сколько в нем было строк и "столбцов"

я сделал так:

// считаем сколько переводов строки
std::ifstream ar("test.dat", std::ios::in|std::ios::binary);
std::istreambuf_iterator<char> begin(ar), end;
int counter = std::count(begin, end, char('\n') );
ar.close();

// сохранием каждый элемент в вектор(кстати тоже надо)
std::vector<double> v;
std::fstream file_in ( "test.dat", std::ios::in );
std::copy (std::istream_iterator<double>(file _in), std::istream_iterator<double>(), back_inserter(v));

// ну и вычисляем сколько было столбцов
int counterX = v.size() / counter;


Но мне чето не очень нравится что нужно проходить по файлу два раза.
Как такое провернуть по-хитрее и по-красивее?

и тут же еще вопрос:

CString m_sInFileText;
// бла бла бла как то ее заполнили
std::basic_stringstream<wchar_t> ss(m_sInFileText.GetString());
std::vector<double> v;
// теперь как вектор v заполнить тем, что лежит в ss?
// пробую так, но естественно не соответствие типов
std::copy (std::istream_iterator<double>(ss), std::istream_iterator<double>(), back_inserter(v));
Kukurudza вне форума Ответить с цитированием
Старый 02.06.2011, 10:20   #2
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

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

Не уверен, но вроде vector - как раз нужная вещь (т.е. динамический массив).
А я бы сделал на односвязных списках.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 02.06.2011, 10:25   #3
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

Не рационально ваше предложение про перепись строк туда сюда. вектор да. действительно контейнер, который подходит для этой задачи, он же и используется.
а зачем односвязные списки?
Kukurudza вне форума Ответить с цитированием
Старый 02.06.2011, 10:31   #4
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Цитата:
а зачем односвязные списки?
Ха, а как вы думаете vector внутри реализован?)
Я просто люблю все делать своими руками и не доверяю левым классам, пусть даже они входят в стандартную библиотеку) Слава богу, с указателями никогда проблем не было и с реализацией односвязных, двусвязных списков, стэков и вообще чего угодно на указателях проблем тоже не было)

Цитата:
Не рационально ваше предложение про перепись строк туда сюда.
Почему перепись? Вы меня, наверное, не так поняли. Вот примерная схема:
Массив строк
| Строка [2,5,6]
| Строка [3,6,7]
| Строка [4,7,8]
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 02.06.2011, 10:34   #5
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

ну спорить не будем что лучше, а что хуже, каждому свое, я предпочитаю STL.
в другом вопрос, как исправить уже существующий мой код? программа большая и переходить на свой написанный контейнер недопустимо.
Kukurudza вне форума Ответить с цитированием
Старый 02.06.2011, 10:40   #6
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Цитата:
ну спорить не будем что лучше
я и не спорю, просто выражаю свое мнение)
Цитата:
я предпочитаю STL
И правильно. Все своими руками - это мои тараканы просто)
Цитата:
и переходить на свой написанный контейнер недопустимо.
Я и не предлагаю) Вы знаете как добавлять в vector новый элемент? Думаю, знаете)
Ну вот, у Вас vector, который хранит строки. А строки - это vector'ы, которые хранят числа. Тогда проблем со считыванием не должно быть, так как размер этой таблицы Вам и не нужен, элементы добавляются динамически)
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 02.06.2011, 10:51   #7
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

Намек понял! ща попробую. попробовал. сделал, благодарю за толчок, как до меня самого не дошло.
а по второму вопросу?

Последний раз редактировалось Kukurudza; 02.06.2011 в 11:01.
Kukurudza вне форума Ответить с цитированием
Старый 02.06.2011, 11:04   #8
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Что-то Вы как-то совсем мудрено пишете. Куча классов и ни одного обычного типа или цикла) Тут уже не ко мне вопросы, тем более про считывание данных.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 02.06.2011, 11:13   #9
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

ну это STL советую почитать
вот кстати решение, вдруг кому понадобится:

Код:
// table.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream"
#include "fstream"
#include "sstream"
#include <algorithm>
#include <vector>

int _tmain(int argc, _TCHAR* argv[])
{
	__int32 numCol(0);
	__int32 numRow(0);

	std::ifstream file_in("test.dat", std::ios::in);
	{
		std::string str;
		std::getline(file_in, str);
		std::basic_stringstream<char> ss(str.c_str());
		while(!ss.eof())
		{
			double temp;
			ss >> temp;
			++numCol;
		};
	};
	file_in.close();

	file_in.open("test.dat", std::ios::in);
	std::vector<double> v;
	std::copy (std::istream_iterator<double>(file_in), std::istream_iterator<double>(), back_inserter(v));
	file_in.close();

	numRow = v.size() / numCol;

	std::cout << "numRow = " << numRow << "\nnumCol = " << numCol << "\n";
	for ( __int32 i = 0, k = 0; i < numRow; ++i )
	{
		for ( __int32 j = 0; j < numCol; ++j, ++k )
		{
			std::cout << v[k] << "\t";
		};
		std::cout << std::endl;
	};

	system("pause");
	return 0;
}

Последний раз редактировалось Kukurudza; 02.06.2011 в 16:04.
Kukurudza вне форума Ответить с цитированием
Старый 02.06.2011, 11:16   #10
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Цитата:
советую почитать
Если даже почитаю - все равно ведь буду всегда ручками все делать) Привычка, да и это намного интереснее, чем использовать STL)
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
чтение таблицы из файла dark_knight_91 Помощь студентам 0 17.05.2011 19:08
С++ Чтение из файла sir.andrey Помощь студентам 9 15.10.2010 16:00
Чтение из файла (Си) VadEr Помощь студентам 3 02.09.2010 21:06
Побитовое чтение символа из таблицы символов в BIOSe Viriat Общие вопросы C/C++ 0 10.01.2010 17:26
Чтение файла [Smarik] Помощь студентам 8 28.04.2008 22:15