Pobieranie danych strumieniem - dlaczego to nie działa?

0

Witam serdecznie,

Może to lamerskie pytanie, ale już 2 godziny nad tym siedzę przeczesałem cała Sieć i nadal nie wiem, jak pobrać dane do rekordu z takiego pliku:

BDX 19950525 9,5 9,5 9,5 9,5 334204
BDX 19950526 9,5 9,5 9,5 9,5 261742
BDX 19950529 9,7 9,7 9,7 9,7 213816
BDX 19950530 8,75 8,75 8,75 8,75 163232
BDX 19950531 8,85 8,85 8,85 8,85 102292
BDX 19950601 8,1 8,1 8,1 8,1 41106
BDX 19950602 8,2 8,2 8,2 8,2 64278
BDX 19950605 8,7 8,7 8,7 8,7 31687

Prosty delimiter (spacja), prawda? To dlaczego poniższy program wywala SIGSEGV? Byłbym wdzięczny za jakieś wskazówki.

#include <iostream>
#include...

using namespace std;

struct rekord{
	char *ticker;
	float open, close;
	float low, high;
	long int vol;
};

int main(int argc, char **argv)
{
    ifstream plikGPW;
    vector<rekord> tablica;
    int ileRekordow = 0;
    char linijka[200];

char *spolka = argv[1];
 

	 strcat(spolka,".dat");
cout << "Otwieram plik: "<<spolka<<"\n";
    plikGPW.open(spolka, ios::in);
    if(!plikGPW) exit(1);

    while(plikGPW.getline(linijka,200)){
        rekord tmp;
    	istringstream strumien(linijka);
//tutaj jest SIGSEGV:
    	strumien >> tmp.ticker >> tmp.open >> tmp.high >> tmp.low >> tmp.close >> tmp.vol;
    	tablica.push_back(tmp);
    	ileRekordow++;
    }
	cout << "Pobrano "<<ileRekordow<<" rekordow\n";
plikGPW.close();
return 0;
}
0

nie sprawdzałem czy to ci działa, ale na oko chyba wiem o co chodzi.
ostatnia wczytana linia jest pusta. więc ja robię zawsze taką konstrukcję:

ifstream we("nazwa_pliku.dat");

string s;
while (getline(we,s))
    if(s!="")
    {
        //wczytywanie
    }
0

Nie wiem po co używasz poczciwego char* zamiast std::string.
Sprawdź ten kod:

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

struct Rekord {
    std::string ticker;
    float open;
    float close;
    float low;
    float high;
    long vol;
    long garbage; // patrz [1]

};

std::ostream& operator<<(std::ostream& os, const Rekord& rekord) {
    os << "Rekord {\n"
        << "  ticker: " << rekord.ticker << "\n" << std::setprecision(12)
        << "  open: " << rekord.open << "\n"
        << "  close: " << rekord.close << "\n"
        << "  low: " << rekord.low << "\n"
        << "  high: " << rekord.high << "\n"
        << "  vol: " << rekord.vol << "\n"
        << "  garbage: " << rekord.garbage << "\n"
        << "}\n";
    return os;
}


int main(int argc, char** argv) {
    using namespace std;

    if (argc > 1) {
        string nazwa_pliku = argv[1];
        nazwa_pliku += ".dat"; 
        cout << "Otwieram plik: " << nazwa_pliku << "\n";

        ifstream plik;
        plik.open(nazwa_pliku.c_str(), ios::in);

        if (!plik) {
            cerr << "plik '" << nazwa_pliku << "' nie daje się otworzyć.\n";
        } else {
            vector<Rekord> tablica;
            string linijka;

            while (getline(plik, linijka)) {
                Rekord tmp;
                stringstream ss(linijka);
                ss >> tmp.ticker >> tmp.garbage >> tmp.open >> tmp.high >> tmp.low >> tmp.close >> tmp.vol;
                // [1] zależy jaką konwencję masz w swoim formacie, nie znam jej... ale jedną wartość z linijki opuszczałeś
                tablica.push_back(tmp);
            }
            cout << "Pobrano " << tablica.size() << " rekordow\n";

            //wyświetlanie rekordów
            for (vector<Rekord>::const_iterator it = tablica.begin(); it != tablica.end(); ++it) {
                cout << *it;
            }
        }
    } else {
        cerr << "Uzytkowanie:\n" << argv[0] << " plik\n";
    }

    return 0;
}
 
0
istream& operator >>(istream& in,Rekord& r)
{
  return in >> r.ticker >> r.garbage >> r.open >> r.high >> r.low >> r.close >> r.vol;
}

...

Rekord tmp;
plik >> tmp;

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