C++ načtení libovolného řádku z CSV – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

C++ načtení libovolného řádku z CSV – C / C++ – Fórum – Programujte.comC++ načtení libovolného řádku z CSV – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Shadow2334
~ Anonymní uživatel
7 příspěvků
23. 10. 2011   #1
-
0
-

Ahoj, potřeboval bych poradit, jak v Céčku docílit toho, abych mohl načíst třeba druhý řádek z CSV souboru, bez toho aby program načetl všechny ostatní.

Napadlo mne, že by se celý CSV dal načíst do pole a pak z toho zobrazit pouze ty a ty prvky.. ale jak CSV načíst do toho pole? 

Díky za pomoc

Nahlásit jako SPAM
IP: 79.127.205.–
Reklama
Reklama
KIIV+42
God of flame
23. 10. 2011   #2
-
0
-

tak nactes pokazdy jeden a zjistis jestli je to ten, co chces... pak uz dal cist nemusis

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Shadow2334
~ Anonymní uživatel
7 příspěvků
23. 10. 2011   #3
-
0
-

díky za odpověď, ale jak načíst pouze jeden? 

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

using namespace std;

int main ()
{
	cout << "Kod\tNazev\t\tCena za kus";
    ifstream inFile ("vyrobky.csv");
    string line;
    int linenum = 0;
    while (getline (inFile, line))
    {
        linenum++;
        cout << "\n";
        istringstream linestream(line);
        string item;
        int itemnum = 0;
        while (getline (linestream, item, ';'))
        {
            itemnum++;
            cout <<item << "\t";
        }
    }
	getchar();
    return 0;
}

ten CSV soubor vypadá takto: 

1;Cihla CV14;50
2;Cihla CL25;45
3;Cihla AT14;60
4;Cihla AT29;74

chtěl bych aby to po zadání čísla 1 - 4 vypsalo jeden celý řádek, který má tuhle hodnotu na první pozici, ale furt s tím ne a ne hnout.


Nahlásit jako SPAM
IP: 79.127.205.–
KIIV+42
God of flame
23. 10. 2011   #4
-
0
-

vsak nacitas po jednom... musis jen porovnat jestli ses na spravne hodnote a pouzit  "break" na ukonceni

(mimochodem dobre je po sobe zavirat pak soubory... )

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Shadow2334
~ Anonymní uživatel
7 příspěvků
24. 10. 2011   #5
-
0
-

tak povedlo se mi to zobrazit pouze jeden řádek podle toho jaké zadám číslo pomocí cyklu a  cout << " \r"   ale to není přesně to co bych chtěl protože ten jeden vybraný řádek chci dále používat, konkrétně uložit do druhého CSV souboru...

takže sjem opět v koncích  

vypadá to nějak takhle: 

int main ()
{
    ifstream inFile ("vyrobky.csv");
    string line;
    int linenum = 0;
	int cislo;
	cout << "Zadejte poradi polozky, kterou chcete objednat: ";
	cin >> cislo;

	cout << "\nKod\tNazev\t\tCena za kus"<< endl;
    while (getline (inFile, line) && cislo!=0)
    {
		while(cislo>0)
		{
			cout << "\r";
			break;
		}
		cout << "";
		cislo--;
        linenum++;
        cout << "";
        istringstream linestream(line);
        string item;
        int itemnum = 0;
        while (getline (linestream, item, ';'))
        {
            itemnum++;
            cout <<item << "\t";
        }
    }
	flushall();
	getchar();
    return 0;
}
Nahlásit jako SPAM
IP: 89.176.151.–
KIIV+42
God of flame
24. 10. 2011   #6
-
0
-

tak ho uloz do nejaky struktury, objektu nebo jineho souboru.. co ti brani?

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Shadow2334
~ Anonymní uživatel
7 příspěvků
24. 10. 2011   #7
-
0
-

nojo, ale jak?  

Nahlásit jako SPAM
IP: 89.176.151.–
KIIV+42
God of flame
24. 10. 2011   #8
-
0
-

existuje taky  ofstream  na vystup do souboru,

vector nebo podobne na ulozeni ... jen hledej - trochu snahy

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Peppy0
Stálý člen
24. 10. 2011   #9
-
0
-

Už z logiky vyplýva, že keď chcem robiť niečo so súborom ta nenačítam len ten jeden riadok ale celý súbor do pamäte, a tam s tým pracujem ako chcem.

Nahlásit jako SPAM
IP: 85.135.129.–
Qt, QML, C++
ondra.holub+1
Stálý člen
25. 10. 2011   #10
-
+2
-
Zajímavé

#9 Peppy
Už z logiky věci vyplývá, že pokud mě zajímá jenom 50. řádek ze souboru, který obsahuje 1000 řádků, je nesmysl číst více než 50 řádků a je nesmysl držet prvních 49 řádků v paměti.

Přístup "načtu všechno do vektoru stringů a pak sáhnu na konkrétní prvek" je, bohužel, dost častý. Ale není to problém, pokud to chci na jednorázovou utilitku, kde je efektivita zcela zbytečná - tam je cokoliv, co funguje, postačující.

Nahlásit jako SPAM
IP: 194.138.12.–
KIIV+42
God of flame
25. 10. 2011   #11
-
0
-

no pokud mluvis zrovna o "efektivite", tak to je potom lepsi nacist cely naraz do pameti a pak s tim dal pracovat (akorat musis dat pozor na velikost souboru)... nejpomalejsi mozne reseni je kvuli kazdymu radku nacitat znova a znova a znova ten samej soubor do zblbnuti

(ale technicky vzato muze taky skoncit v mezipameti systemu - tj. tak jak tak v ram)

samozrejme existuji i dobre duvody... napriklad soubor se meni... ale to taky muzes obcerstvovat podle casu zmeny souboru a jen ten obcas zkontrolovat

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondra.holub+1
Stálý člen
25. 10. 2011   #12
-
0
-

#11 KIIV
No dobře. A proč je tedy efektivnější držet si v paměti i ty předešlé řádky, které nepotřebuji? A proč je efektivnější načíst tam i to, co je za tím řádkem, který potřebuji?

Sice se vždycky dá najít případ, kdy bude nějaká varianta lepší než jiná, ale pokud to beru obecně, tak ten přínos načtení celého souboru skutečně nevidím. A to už raději nemluvím o tom, kdy ten soubor bude na nějakém pomalejším filesystému - fyzicky se může nacházet třeba na jiném konci světa, nebo stačí i na DVD. Nebo to může být stdin - pak nevidím důvod, aby program nechal uživatele nacpat (třeba z klávesnice) spoustu dat, které pak ani nevyužije.

Nahlásit jako SPAM
IP: 194.138.12.–
KIIV+42
God of flame
25. 10. 2011   #13
-
0
-

#12 ondra.holub
efektivnejsi to je, pokud to neni jednorazova utilita a pouziva se to jako "pseudo" databaze... (otvirani/zavirani, prochazeni neco stoji)

pro jeho priklad jsem mu navrhl vector jen na ulozeni jednotlivejch polozek co jsou na radku (aby to nemusel rosekavat pokazdy znova)... ne na ukladani predchozich radku (nemel pozadavek ze by to chtel pouzit vickrat treba z ruznych mist... )

micmene todle jsou proste reseni "zadratovany"... hodi se to akorat pro hobby programovani  -  jakmile se dostanes k vetsimu projektu, najednou tu bude pozadavek obecnosti, znovupouzitelnosti a podobne.. treba obsahlej konfiguracni soubor budes tezko nacitat pokazdy znova a hledat nastaveni ktere zrovna pozadujes ... kdyz to udelas dobre tak to nebude ani moc velky a jeste to bude rychly... (zalezi jen na mnozstvi "omezeni", kontrol a podobne)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Peppy0
Stálý člen
25. 10. 2011   #14
-
0
-

#10 ondra.holub

...je nesmysl číst více než 50 řádků a je nesmysl držet prvních 49 řádků v paměti.

A potom ťa bude zaujímať 80-tý riadok, 120. riadok, potom po čase zistíš, že ti treba 30-tý riadok. Opäť po čase ti bude treba 100. riadok, potom zase 50. riadok, and so on and so futher, fakt je "efektívne" prechádzať riadky Xkrát, namôjveru efektivita jak remeň... Aj keby si mal 100 000 000 riadkový konfigurák, je oveľa jednoduchšie si ho načítať a prejsť raz a manipulovať s ním v pamäti. Každý väčší program (nejakou väčšiou utilitou začínajúc) furt načíta konfig raz, ten naparsuje, všetko nastaví a ďalej neprechádza súbor (časovo náročnejšie, než šáhnuť do naparsovaného vektora). Je to oveľa lepšie držať v pamäti, kde to zaberie 4 MB, než v súbore, ktorý budem musieť prechádzať a počítať pozície rôznych znakov.

Pamäťové nároky? Tých tisíc riadkov CSV, čo by do šírky, museli byť veľmi, veľmi dlhé. Výkon dnešných PC je ohromný, takže pokiaľ nemáš rachotinu s 256 MB RAM a Intel Pentium 3, väčšie súbory (~5MB) sú pre procáky v pohode.

Nahlásit jako SPAM
IP: 85.135.184.–
Qt, QML, C++
ondra.holub+1
Stálý člen
26. 10. 2011   #15
-
+1
-
Zajímavé

#14 Peppy

A potom ťa bude zaujímať 80-tý riadok, 120. riadok, potom po čase zistíš, že ti treba 30-tý riadok. Opäť po čase ti bude treba 100. riadok, potom zase 50. riadok, and so on and so futher, fakt je "efektívne" prechádzať riadky Xkrát, namôjveru efektivita jak remeň...

Nebudu se hádat. Evidentně se pletu, když nevidím nutnost to celé znovu načítat, až mě začne zajímat nějaký jiný řádek. Evidentně není normální projít ten vstup jednou (tady ještě spor není) a uložit si z něj jenom to, co mě zajímá (tady už se neshodujeme). Nikde jsem nenapsal, že musím vždy začít čtení od začátku (naopak jsem zmínil např. čtení ze stdin, kde se to prostě najednou načíst musí). Pokud mě zajímá v tom vstupu více míst, tak samozřejmě skončím, až je najdu všechny. Já si (zřejmě chybně) myslím, že když už vím, že nic dalšího z toho vstupu nebudu potřebovat, tak to prostě nebudu číst. Evidentně je lepší to nejdřív celé načíst a pak z toho 99% vyhodit. Např. pokud konfigurační soubor obsahuje i poznámky, tak teď už vím, že si je mám uložit a pak je při hledání něčeho konkrétního jenom přeskakovat. Hlavně nezjišťovat hned při čtení, že v tom pro ten program nic zajímavého není, to je předčasné.

Je to stejné jako obvyklé "enterprise" řešení úlohy typu "očíslujte vzestupně všechny řádky celého souboru". Správné enterprise řešení je načíst celý soubor do vektoru v paměti a pak ten vektor postupně projít a vypisovat na výstup (samozřejmě použít vektor, list nebrat, co kdyby někdy někdo potřeboval náhodný přístup. Ale ještě víc "enterprise" je naprogramovat vlastní vektor). Špatné řešení (vhodné jenom pro hobby programy) je postupné čtení, které to rovnou čísluje a cpe do výstupu. Výhody enterprise řešení: dá to stejně práce jako hobby řešení, načítání může dělat jiný team než vypisování, sežere to víc paměti, první řádek výstupu mám k dispozici až po načtení celého vstupu. Nevýhody hobby řešení: není třeba dělat extra verzi pro čtení souboru někde z internetu, nečte to zbytečně konec vstupu v případě, kdy už vím, že z něj nic nevyužiju (takže vlastně nemusím poznat, že konec vstupu nejde číst), výstup můžu tvořit už ve chvíli, kdy ještě nemám načten kompletní vstup.

Rozdíl pracnosti vývoje:

  • načtení jednoho řádku - potřebuji v obou variantách - stejné
  • zpracování řádku tak, abych zjistil, jestli mě zajímá - potřebuji v obou variantách - stejné
  • uložení načteného řádku - buď ukládám všechno nebo jenom ten, který mě zajímá - pracnost programování stejná, při běhu programu samozřejmě proběhne jenom pro ty řádky, které ukládám

A mimochodem, zadání bylo: Ahoj, potřeboval bych poradit, jak v Céčku docílit toho, abych mohl načíst třeba druhý řádek z CSV souboru, bez toho aby program načetl všechny ostatní. Jako řešení nenačítání ostatních řádků mi nepřipadá načtení všech.

Nahlásit jako SPAM
IP: 194.138.12.–
Pudni tvor+2
Stálý člen
29. 10. 2011   #16
-
0
-

   

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

using namespace std;

int  ZjistiCisloRadku(const string& line);
void PrevedStrednikyNaTabulatory(string& line);

int main ()
{
  int vypsatRadek = 2;
  
  cout << "Kod\tNazev\t\tCena za kus\n";
  ifstream inFile ("vyrobky.csv");

  string line;  
  while (getline (inFile, line)) {
    int cisloRadku = ZjistiCisloRadku(line);
    if (cisloRadku == vypsatRadek) {
      PrevedStrednikyNaTabulatory(line);
      cout << line << '\n';
      break;
    }
  }

  return 0;
}

int ZjistiCisloRadku(const string& line)
{
  int delkaCisla = line.find(';');  
  string retezecSCislem = line.substr(0, delkaCisla);  
  return atoi(retezecSCislem.c_str());  
}

void PrevedStrednikyNaTabulatory(string& line)
{  
  for (int i = 0; i < line.length(); i++) {
    if (line[i] == ';') line[i] = '\t';
  }      
}

Nahlásit jako SPAM
IP: 90.180.213.–
volftomas0
Newbie
12. 12. 2011   #17
-
0
-

Drzet cely (potencialne obri) soubor v pameti je podle mne blbost, tohle bych nechal na cache operacniho systemu.

Ondra.holub ma pravdu v tom, ze otazka byla vyslovene formulovana tak, ze nacitani vseho je nezadouci.

Nicmene pokud by zadouci bylo, resil bych to tak, ze bych prosel jednou soubor a ulozil si akorat seek na cisla radku, aniz bych drzel radky jako takove v pameti. Pak bych akorat seeknul na prislusny byte a nacetl cely radek z souboru (ktery by nejspis byl v cache, tedy defakto ramce).

Nahlásit jako SPAM
IP: 81.200.55.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 67 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý