[C++] Prosta pętla

Awatar użytkownika
Psycho
Użytkownik
Użytkownik
Posty: 370
Rejestracja: 23 gru 2008, o 09:37
Płeć: Mężczyzna
Lokalizacja: Przemyśl/Kraków
Podziękował: 59 razy
Pomógł: 68 razy

[C++] Prosta pętla

Post autor: Psycho »

Mam taki problemik, iż w założeniu chcę sobie wczytać dowolny ciąg znaków i policzyć ile ich jest po czym zakończyć wczytywanie. Napisałem takie coś:

Kod: Zaznacz cały

while (cin.peek() )
{
          i++;
          
          if (cin.peek() == EOF || cin.peek() == '\n') break;
}
ale to nie działa, gdyż pętla nie chce się zakończyć. W zasadzie to nie mam pojęcia, czy to co napisałem w ogóle ma sens, ale mam nadzieję, że idea jest jasna. Pytanie w jaki sposób mam to zrobić :?:
spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

[C++] Prosta pętla

Post autor: spajder »

Kod: Zaznacz cały

cin.gcount()
Moraxus
Użytkownik
Użytkownik
Posty: 223
Rejestracja: 23 lis 2008, o 18:10
Płeć: Mężczyzna
Podziękował: 3 razy
Pomógł: 79 razy

[C++] Prosta pętla

Post autor: Moraxus »

Tak dla wyjaśnienia, to funkcja peek() pobiera znak ze strumienia, ale go nie usuwa.
Oznacza to, że przy każdym przejściu przez pętlę zczytywany jest ten sam znak.
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

[C++] Prosta pętla

Post autor: matshadow »

nie lepiej tak?

Kod: Zaznacz cały

string s;
getline(cin, s);
cout<<s.size()<<endl;
Awatar użytkownika
Psycho
Użytkownik
Użytkownik
Posty: 370
Rejestracja: 23 gru 2008, o 09:37
Płeć: Mężczyzna
Lokalizacja: Przemyśl/Kraków
Podziękował: 59 razy
Pomógł: 68 razy

[C++] Prosta pętla

Post autor: Psycho »

spajder pisze:

Kod: Zaznacz cały

cin.gcount()
Mógłbyś napisać krótki kod, bo nie bardzo wiem gdzie i jak mam to umieścić
Moraxus pisze:Tak dla wyjaśnienia, to funkcja peek() pobiera znak ze strumienia, ale go nie usuwa.
Oznacza to, że przy każdym przejściu przez pętlę zczytywany jest ten sam znak.
Dzięki, o tym nie wiedziałem. To dlatego pętla nie działała. Pytanie czy jest jakaś podobna funkcja, która w ten sposób była by efektywna
matshadow pisze:nie lepiej tak?

Kod: Zaznacz cały

string s;
getline(cin, s);
cout<<s.size()<<endl;
Niestety nie potrafię tego przenieść na C++
Moraxus
Użytkownik
Użytkownik
Posty: 223
Rejestracja: 23 lis 2008, o 18:10
Płeć: Mężczyzna
Podziękował: 3 razy
Pomógł: 79 razy

[C++] Prosta pętla

Post autor: Moraxus »

krzysiek_ pisze:
matshadow pisze:nie lepiej tak?

Kod: Zaznacz cały

string s;
getline(cin, s);
cout<<s.size()<<endl;
Niestety nie potrafię tego przenieść na C++
To jest w C++
Co do funkcji gcount() to zwraca ona ilość znaków pobranych przy ostatnim pobieraniu znaków ze strumienia, więc możemy to zapisać tak jak podał matshadow:

Kod: Zaznacz cały

string s;
getline(cin, s);
cout<<s.size()<<endl;
albo

Kod: Zaznacz cały

string s;
getline(cin, s);
cout<<cin.gcount()<<endl;
Wynik będzie ten sam.
Awatar użytkownika
Psycho
Użytkownik
Użytkownik
Posty: 370
Rejestracja: 23 gru 2008, o 09:37
Płeć: Mężczyzna
Lokalizacja: Przemyśl/Kraków
Podziękował: 59 razy
Pomógł: 68 razy

[C++] Prosta pętla

Post autor: Psycho »

Mówiąc szczerze, to chodziło mi o coś trochę innego, gdyż zliczanie wyrazów za pomocą cin.gcount w tym wypadku niezastosowalne. Konkretnie to chciałem rozwiązać m.in. to zadanie ze spoj.pl ( ):
1911. Zliczanie liczb i wyrazów
Kod zadania: KC010

Napisz program, który liczy, ile wyrazów i liczb znajduje się w podanej linii.
Wejście

Na wejście programu podana zostanie pewna ilość zestawów danych. Poszczególne zestawy składają sie z liczb całkowitych i wyrazów (wyraz = ciąg liter) rozdzielonych spacjami oraz kończą się znakiem nowej linii.
Wyjście

Na wyjściu ma się pojawić ilość liczb i wyrazów znajdujących się w poszczególnych liniach. Ilość liczb należy oddzielić spacją od ilości wyrazów, a po ilości wyrazów ma się pojawić znak nowej linii.
Przykład

Wejście:

Romek ma 2 koty i 3 psy
2 plus 2 jest rowne 4

Wyjście:

2 5
3 3
lecz niestety po prostu już nie mam pomysłu jak to zrobić. Jakby ktoś mógł zobrazować rozwiązanie króciutkim kodem jak konkretnie policzyć te liczby i wyrazy to byłbym bardzo wdzięczny.
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

[C++] Prosta pętla

Post autor: matshadow »

No to tak, moje rozwiązanie:

Kod: Zaznacz cały

#include <iostream>
#include <cctype>
using namespace std;

int main()
{
   ios_base::sync_with_stdio(0);
	string s;
	while(getline(cin,s))
	{
        int licz=0,slow=0;
        if(isalpha(s[0])) slow++;
		  else licz++;
        for(int i=1;i<s.size()-1;i++)
			if(isspace(s[i]))
			{
				if(isdigit(s[i+1])) licz++;
				else slow++;
			}
		printf("%d %d
",licz,slow);
	}
	//system("pause");
	return 0;
}
isalpha(znak) - sprawdza czy znak jest literą
isdigit(znak) - sprawdza czy znak jest cyfrą
isspace(znak) - sprawdza czy znak jest spacją.
Otóż jak napotkasz spację to wtedy patrzysz, czy kolejny znak jest cyfrą - wtedy dodajesz ilość liczb. Jak nie jest liczbą, to dodajesz ilość słów a w pętli porównuję ze sobą znaki kolejne od 1, więc muszę dodatkowo sprawdzić pierwszy znak wczytywanego stringa
Awatar użytkownika
Psycho
Użytkownik
Użytkownik
Posty: 370
Rejestracja: 23 gru 2008, o 09:37
Płeć: Mężczyzna
Lokalizacja: Przemyśl/Kraków
Podziękował: 59 razy
Pomógł: 68 razy

[C++] Prosta pętla

Post autor: Psycho »

Dzięki! M.in nie wiedziałem właśnie jak sprawdzić, czy dany znak jest spacją. Mam jeszcze takie 2 pytania: czy biblioteka "cctype" jest potrzebna do tych wszystkich isalpha, isdigital itd. i czy istnieje taka funkcja, która sprawdza czy znak jest końcem linii
Moraxus
Użytkownik
Użytkownik
Posty: 223
Rejestracja: 23 lis 2008, o 18:10
Płeć: Mężczyzna
Podziękował: 3 razy
Pomógł: 79 razy

[C++] Prosta pętla

Post autor: Moraxus »

Z końcem linii nie będzie problemu, wystarczy dany znak porównać z '\n' np:

Kod: Zaznacz cały

char c;
(...)
if(c=='\n')
    //znak jest końcem linii
Tylko nie wiem do czego Ci to potrzebne, skoro funkcja getline zastosowana w programie matshadowa pobiera pojedyńcze linie.
Ostatnio zmieniony 20 maja 2009, o 16:31 przez Moraxus, łącznie zmieniany 1 raz.
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

[C++] Prosta pętla

Post autor: matshadow »

Tak, cctype jest wymagana, chyba że sobie naklepiesz swoje własne funkcje isalpha itp
Awatar użytkownika
Psycho
Użytkownik
Użytkownik
Posty: 370
Rejestracja: 23 gru 2008, o 09:37
Płeć: Mężczyzna
Lokalizacja: Przemyśl/Kraków
Podziękował: 59 razy
Pomógł: 68 razy

[C++] Prosta pętla

Post autor: Psycho »

To jeszcze nie ten poziom, lepiej użyć gotowców :)
Moraxus pisze:Z końcem linii nie będzie problemu, wystarczy dany znak porównać z '\n' np:

Kod: Zaznacz cały

char c;
(...)
if(c=='\n')
    //znak jest końcem linii
Tylko nie wiem do czego Ci to potrzebne, skoro funkcja getline zastosowana w programie matshadowa pobiera pojedyńcze linie.
Może i nie będzie, ale nigdy nic nie wiadomo, a wiem, że z tym też miałem problem :P
ODPOWIEDZ