odczyt z plików - problem z wybraniem określonej ilość elementów

0

Witam, mam zadanie, w którym musze odczytać z pliku tekstowego n liczb. W pierwszym wierszu zapisana jest ilość liczb, które musimy pobrać, a w drugim znajdują się liczby do pobrania - nie znamy ich ilość . Mój problem polega na tym, iż nie wiem jak wybrać n - liczb, zapisanych w jednej linijce nie znając ich długości, a potem przejść do innej linii. Czy mógłby ktoś zasugerować z czego korzystać?

Plik wygląda tak :

3
3 5 6 7 2 1 5
2
9 0 5 1 2 
6
1 1 1 3 9 2 1 5 6 2 4
2

getline, żeby pobrać całą linijkę, a potem czytasz z tej linijki jak z pliku za pomocą stringstream.

1

W pierwszym wierszu zapisana jest ilość liczb, które musimy pobrać, a w drugim znajdują się liczby do pobrania - nie znamy ich ilość

??? Jak ta liczba jest zapisana to jej nie znamy?

W treści zadania mówisz o 2 liniach, w przykładzie jest 6. Czy to na pewno dobry przykład? Może przeklej treść zadania.

0

@kq: Mam na myśli to, że 3, 2, 6 oznaczają ile liczb mamy pobrać z ciągu poniżej
tzn: dla 3 pobieramy 3, 5, 6 ; dla 2 - 9, 0 itd.

3

jest wiele sposobów, zależnie od warunków brzegowych, to będzie dobrze lub źle:

while (std::cin >> n) {
    auto it = std::istream_iterator<int>{std::cin};
    std::vector<int> v;
    v.reserve(n);
    std::copy_n(it, n, std::back_inserter(v));
    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');

    // do something with v
}
0

@4matey: odpowiadaj na temat w postach, nie w komentarzach...

a można zrobić bez używania sstream? — 4matey dziś, 14:09

A bardzo Ci sstream przeszkadza? Jak tak, to można też parsować ręcznie, nie powinno to bić ZBYT kłopotliwe... Mianowicie -- po getline wycinasz z napisu podnapis do najbliższej spacji, zamieniasz to na liczbę, a potem robisz to samo (tyle razy ile trzeba) na kolejnych kawałkach tego napisu...

0

@koszalek-opalek: Właśnie tak chciałem zrobić tylko jak wyciąć podnapis ? Próbowałem z : napis[ i ] != " " , ale nie działa mi to.

 for(int i=0;  i < napis.size() ; i++)
{
     if (napis[ i ] != " ")              // tutaj wyskakuje mi błąd
     podnapis += napis[i];
}
1
4matey napisał(a):

@koszalek-opalek: Właśnie tak chciałem zrobić tylko jak wyciąć podnapis ? Próbowałem z : napis[ i ] != " " , ale nie działa mi to.

 for(int i=0;  i < napis.size() ; i++)
{
     if (napis[ i ] != " ")              // tutaj wyskakuje mi błąd
     podnapis += napis[i];
}

if(napis[i]!=' ') ...

W sumie można zrobić prościej o ile dane nie wprowadza człowiek (bo nawet w danych co podałeś po wierszu : 9 0 5 1 2 masz spację na końcu, a z tą spacją nie działa):

#include <iostream>
using namespace std;

int main()
{
	int t,n,value,skiped;
	for(cin>>t;t--;cout<<endl)
	{
		for(cin>>n;n--;cout<<value<<' ') cin>>value;
		while(cin.get()!='\n') cin>>skiped;
	}
	return 0;
}

Można jednak podmienić while(cin.get()!='\n') cin>>skiped;:
na:

		while(true)
		{
			while((isspace(skiped=cin.peek()))&&(skiped!='\n')) cin.get();
			if(skiped=='\n') break;
			cin>>skiped;
		}

wtedy mogą być zbędne spację i/lub tabulacje.

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