Wczytanie pliku csv

0

Hej,

Ponownie mam problem z wczytaniem danych z pliku CSV stworzonego przez Matlaba. Wczytywanym plikiem jest obraz 1920x1080. Program działa, ale zapętla się w pętli while (nie wiem dlaczego?). W pliku mam 2073600 liczb. Problem mam też z tym, że w wierszu są one zapisane
liczba;liczba;...;liczba;liczba [ENTER]
a ja odczytując liczba,char napotykam na końcu enter który tym char'em nie jest..

ifstream czytaj("obraz.csv");
	if (czytaj.good())
	{
		cout << "ok" << endl;
	}
	else {
		cout << "BLAD" << endl;
	}
	int z; //znak
	char a;
	int c=0;
	while (!czytaj.eof())
	{
		czytaj >> z >> a;
		//cout << z;
		c++;
	
		
	}
	cout <<c<< endl;
	czytaj.close();

Będę wdzięczna za podpowiedź, bo już nie mam pomysłu.. :(

0

czytanie z pliku nie jest mega szybkie, ile czekasz na zakończenie tej pętli?

0

Bardzo długo. A jestem pewna, że przeleci przez wszystkie dane, bo pętla wykonuje się ponad 2073600 i nie chce się skończyć..

0

hmn ciekawe

0

Piszę podobny kod wczytuję 1000+ wierszy z pliku *.txt robię tak :

std::fstream file_pointer(file_name);
char* buf;
file_pointer.seekg(0, std::ios::end);
int length = file_pointer.tellg();
file_pointer.seekg(0, std::ios::beg);
buf = new char[length];
file_pointer.read(buf, length);
file_pointer.close();
explode(buf, '\n', elixir_lines);
elixir_lines.pop_back();
delete buf;
 

explode - rozbija plik na vector po znaku końca linii. potem trzeba jeszcze usunąć ostani wiersz vectora bo jest tam znak EOF
wczytanie i rozbicie działa szybciej niż np wczytanie przez getline * fgetc * << sprawdzałem czas dziś, ale może zaraz ktoś mnie poprawi :)

0

raczej tak jest szybciej, z tego co pamiętam strumienie nie są najlepszą opcją więc raczej z tego powodu nikt cię nie poprawi

0

Ten sposób ma niestety pewien minus, dlugość pliku może być większa niż int lub np unsigned long.

 tellg() 

zwraca wartość streampos, wymyśliłem więc coś takiego

	
        std::fstream file_pointer(file_name);
	 if (file_pointer)
         {
		char* buf;
 		unsigned long len = ULONG_MAX;
 		std::string str_buf="";
		file_pointer.seekg(0, std::ios::end);
 		std::streampos length = file_pointer.tellg();
 		file_pointer.seekg(0, std::ios::beg);

 		while (length > ULONG_MAX)
 		{
			buf = new char[len];
			file_pointer.read(buf, len);
			str_buf += buf;
			length -= ULONG_MAX;
		}
		len = length;
		buf = new char[len];
		file_pointer.read(buf, len);
 		str_buf += buf;
		file_pointer.close();
		delete buf;
 		explode(str_buf, '\n', elixir_lines);
		elixir_lines.pop_back();
	}
	else std::cout << "Brak pliku!" << std::endl; 

cały czas mam warning "possible data loss" (po wyjściu z while), z tego co czytałem o streampos może odejmować i porównywać, zastanawiam się tylko czy:

std::streampos length > ULONG_MAX  

nie spowoduje że length zostanie najpier przekonwertowane na unisgned long? Podpowie ktoś? Nie do końca to dotyczy oryginalnego problemu, ale nie chcę zakładać drugiego tematu praktycznie o tym samym:)

0

warring przez to że nie usuwasz tego buf tylko cały czas tworzysz na nowo

0

Masz rację, jednak nie to jest przyczyną warninga.

 unsigned long len = ULONG_MAX;
		file_pointer.seekg(0, std::ios::end);
		std::streamoff length = file_pointer.tellg();
		file_pointer.seekg(0, std::ios::beg);
		while (length > len)
		{
			char * buf = new char[len];
			file_pointer.read(buf, len);
			str_buf += buf;
			length -= len;
			delete buf;
		}
		len = static_cast<unsigned long>(length);
		char * buf = new char[len];
		file_pointer.read(buf, len);
		str_buf += buf;
		file_pointer.close();
		delete buf;

dodanie rzutowania po pętli usunęło warninga :) Dzięki za pomoc.

Co do usuwania buf to teraz jest ok?

0

Kiedyś się bawiłem takim csv-em po to by pokazać, że można podejść do problemu w różny sposób, ale na pewno nie taki jak podeszli twórcy funkcji str_getcsv w PHP... Natomiast kod i rozważania są napisane w C++ Nie jest to rozwiązanie optymalne, bo robione w innym celu, ale może pomogą takie wariacje: Cykl na ten temat

1 użytkowników online, w tym zalogowanych: 0, gości: 1