[C++] Zliczanie linii w tekście

xdominika
Użytkownik
Użytkownik
Posty: 81
Rejestracja: 14 lis 2019, o 22:59
Płeć: Kobieta
wiek: 19
Podziękował: 23 razy

[C++] Zliczanie linii w tekście

Post autor: xdominika »

Mam napisać program, który prosi użytkownika o wpisanie tekstu, drukuje ten tekst i zwraca liczbę linii. Czy ktoś może wie, w jaki sposób mogę zliczyć właśnie ilość linii? Niestety nie mam żadnego pomysłu.

Kod: Zaznacz cały

string tekst (string s)
{
    cout<<"Prosze wpisac teskt: ";
    getline(cin,s);
    cout<<"\""<<s<<"\"";
    cout<<endl;
}
Ostatnio zmieniony 7 gru 2020, o 08:03 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
Awatar użytkownika
Dasio11
Moderator
Moderator
Posty: 10204
Rejestracja: 21 kwie 2009, o 19:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 40 razy
Pomógł: 2358 razy

Re: String c++.

Post autor: Dasio11 »

Polecenie jest nieprecyzyjne - skoro możliwe ma być wpisanie wielu linii, to skąd program ma wiedzieć, kiedy tekst się kończy?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: String c++.

Post autor: Afish »

Dasio11 pisze: 6 gru 2020, o 20:42 skąd program ma wiedzieć, kiedy tekst się kończy?
Gdy już nic nie będzie w strumieniu wejścia. Aż chciałoby się rzec "jak się skończy, to się skończy".
Awatar użytkownika
Dasio11
Moderator
Moderator
Posty: 10204
Rejestracja: 21 kwie 2009, o 19:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 40 razy
Pomógł: 2358 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Dasio11 »

A konkretniej? Jeśli użytkownik zechce wpisać

Kod: Zaznacz cały

Po cichu
Po wielkiemu cichu
to która instrukcja w C++ sprawi, że program przestanie czekać na wejście po drugiej linijce, a po pierwszej nie?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Afish »

http://www.cplusplus.com/reference/istream/istream/read/ lub http://www.cplusplus.com/reference/istream/istream/readsome/

Tu nawet nie trzeba bawić się w buforowanie powyżej biblioteki standardowej, wystarczy http://www.cplusplus.com/reference/istream/istream/get/ i zliczanie po znaku (lub parze znaków w kodowaniach, gdzie nowa linia wymaga więcej oktetów).

Przy czym całe Twoje wyrażenie "po drugiej linijce" jest niepoprawne koncepcyjnie. Program powinien wczytać cały strumień wejścia, nie powinien przejmować się "czekaniem", bo to załatwia system operacyjny i biblioteka standardowa buforując wejście. Może nie być żadnego "czekania", jeżeli wejście jest przekierowane z pliku.
Awatar użytkownika
Dasio11
Moderator
Moderator
Posty: 10204
Rejestracja: 21 kwie 2009, o 19:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 40 razy
Pomógł: 2358 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Dasio11 »

W jaki konkretnie sposób proponujesz użyć tych funkcji? Bo ja twierdzę, że nie da się tego zrobić tak, żeby program działał w sposób opisany w poleceniu.

Oczywiście łatwo naprawić ten problem, na przykład każąc użytkownikowi z góry zadeklarować długość tego co napisze, albo ustalając z nim specjalny znak oznaczający koniec wejścia. Ale w treści zadania nie ma o tym ani słowa, więc jeśli faktycznie o takie rozwiązanie chodziło, to pozostaje mi tylko podtrzymać swoją początkową tezę: polecenie jest nieprecyzyjne.

Afish pisze: 7 gru 2020, o 10:24Przy czym całe Twoje wyrażenie "po drugiej linijce" jest niepoprawne koncepcyjnie. Program powinien wczytać cały strumień wejścia, nie powinien przejmować się "czekaniem", bo to załatwia system operacyjny i biblioteka standardowa buforując wejście. Może nie być żadnego "czekania", jeżeli wejście jest przekierowane z pliku.
Mnie właśnie chodzi o to, jaka to instrukcja przeczyta "cały strumień wejścia" w sytuacji, kiedy użytkownik wpisuje tekst z klawiatury? Bo ja nie słyszałem o takiej instrukcji.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Afish »

Dasio11 pisze: 7 gru 2020, o 11:47 W jaki konkretnie sposób proponujesz użyć tych funkcji? Bo ja twierdzę, że nie da się tego zrobić tak, żeby program działał w sposób opisany w poleceniu.
W pętli odczytywać wejście aż do końca strumienia i szukać znaków nowej linii. Możesz wczytywać czymkolwiek, getem, getlinem, readem, jak Ci wygodniej.
Dasio11 pisze: 7 gru 2020, o 11:47 Oczywiście łatwo naprawić ten problem, na przykład każąc użytkownikowi z góry zadeklarować długość tego co napisze, albo ustalając z nim specjalny znak oznaczający koniec wejścia. Ale w treści zadania nie ma o tym ani słowa, więc jeśli faktycznie o takie rozwiązanie chodziło, to pozostaje mi tylko podtrzymać swoją początkową tezę: polecenie jest nieprecyzyjne.
To jest niepotrzebne, nie musisz wiedzieć, jak dużo użytkownik chce podać, bo jak już skończy podawać, to masz koniec strumienia. Oznaczanie końca wejścia specjalnym znakiem też jest niepotrzebne, bo koniec wejścia oznacza się zamknięciem strumienia. Tak jak na kartce papieru, jak kartka się "kończy", to jest "koniec", nie musisz na końcu kartki rysować jakiegoś kwadracika do oznaczenia końca, bo wystarczy fizyczne ograniczenie.
Dasio11 pisze: 7 gru 2020, o 11:47 Mnie właśnie chodzi o to, jaka to instrukcja przeczyta "cały strumień wejścia" w sytuacji, kiedy użytkownik wpisuje tekst z klawiatury? Bo ja nie słyszałem o takiej instrukcji.
No przecież podałem. Strumień nie ma pojęcia, skąd bierze dane, może to być plik, konsola, named pipe, bezpośrednio z pamięci, cokolwiek innego. Jak chcesz zakończyć strumień w konsoli, to robisz to przez CTRL+D na Linuksie lub CTRL+Z na Windowsie, lub jeszcze czymś innym w zależności od środowiska.
Awatar użytkownika
Dasio11
Moderator
Moderator
Posty: 10204
Rejestracja: 21 kwie 2009, o 19:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 40 razy
Pomógł: 2358 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Dasio11 »

Będę się upierał, że o ile w kontekście czytania z pliku sensowne są sformułowania "nic nie będzie w strumieniu" albo "cały strumień wejścia" - o tyle przy wpisywaniu z klawiatury, gdzie dane są tworzone w czasie rzeczywistym, te wyrażenia już sensu nie mają. A ponieważ według polecenia program ma wczytać dane wpisane przez użytkownika, a nie pobrać je z pliku, dlatego od początku dopytuję jak powinien wyglądać program działający właśnie w tej sytuacji.

Po Twoim ostatnim poście rozumiem, że cały czas miałeś na myśli sprawdzanie flagi końca strumienia (EOF). Szczerze mówiąc nie spotkałem się nigdy z taką praktyką, gdy tekst ma być wpisany z klawiatury. Zresztą w internecie ledwo można się dokopać do informacji, jak na Windowsie poprawnie zakończyć strumień w konsoli - trzeba wcisnąć kolejno ENTER, CTRL+Z, ENTER (a zrobić tego tak, żeby wejście nie kończyło się znakiem nowej linii, chyba w ogóle się nie da).

Biorąc to pod uwagę nie twierdzę już, że zadania nie da się rozwiązać w sposób zgodny z treścią. Podtrzymuję natomiast postulaty o konieczności doprecyzowania polecenia, bo wymaganie od użytkownika, żeby po wpisaniu tekstu w konsoli wstukał kombinację końca strumienia, zdecydowanie nie wydaje mi się rozwiązaniem oczywistym.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Afish »

Dasio11 pisze: 7 gru 2020, o 21:45 Będę się upierał, że o ile w kontekście czytania z pliku sensowne są sformułowania "nic nie będzie w strumieniu" albo "cały strumień wejścia" - o tyle przy wpisywaniu z klawiatury, gdzie dane są tworzone w czasie rzeczywistym, te wyrażenia już sensu nie mają. A ponieważ według polecenia program ma wczytać dane wpisane przez użytkownika, a nie pobrać je z pliku, dlatego od początku dopytuję jak powinien wyglądać program działający właśnie w tej sytuacji.
Trudno ¯\_(ツ)_/¯
Dasio11 pisze: 7 gru 2020, o 21:45 Po Twoim ostatnim poście rozumiem, że cały czas miałeś na myśli sprawdzanie flagi końca strumienia (EOF). Szczerze mówiąc nie spotkałem się nigdy z taką praktyką, gdy tekst ma być wpisany z klawiatury. Zresztą w internecie ledwo można się dokopać do informacji, jak na Windowsie poprawnie zakończyć strumień w konsoli - trzeba wcisnąć kolejno ENTER, CTRL+Z, ENTER (a zrobić tego tak, żeby wejście nie kończyło się znakiem nowej linii, chyba w ogóle się nie da).
Każde narzędzie z core utilsów działa w taki sposób, a POSIX wymaga nowej linii na końcu każdego wejścia, więc raczej zaskakującym jest, że się z tym nie spotkałeś.
Ponury123
Użytkownik
Użytkownik
Posty: 128
Rejestracja: 5 lip 2015, o 14:48
Płeć: Mężczyzna
Lokalizacja: nie wiem
Podziękował: 11 razy
Pomógł: 24 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Ponury123 »

Afish, możesz proszę podać kilka z takich narzędzi, zaciekawiłeś mnie tematem chciałbym o tym poczytać.

xdominika, bo Panowie tutaj trochę zaczęli odbiegać od samego pytania, generalnie Twoim celem jest znalezienie znaków końca linii i zliczenie ich, oraz zapis wpisanego tekstu. Dasio11 przedstawił koncepcję, że należało by dodać jakaś dodatkową instrukcję np. wpisz koniec aby zakończyć, moim zdaniem możesz tak zrobić, będzie ok, natomiast Afish wykazał, że tak naprawdę nie potrzebujesz tej instrukcji, możesz założyć, że wpisywanie kończy wraz z końcem strumienia wejścia, wersja o tyle lepsza, że działa niezależnie od tego skąd strumień jest brany, czyli tę samą funkcję bez modyfikacji z powodzeniem można będzie użyć do wersji z wczytywaniem np. z pliku. Ja osobiście dodałbym jeszcze wersję, że można w sposób dynamiczny wypisywać ilość linii, ale w terminalu to raczej nie będzie przejrzyste, potrzebowałabyś jeszcze do tego jakieś ekstra okienko.

PS. widziałem Twoje podziękowanie, doceniam, od razu zrobiło mi się miło ;)
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Afish »

Ponury123 pisze: 8 gru 2020, o 12:11 Afish, możesz proszę podać kilka z takich narzędzi, zaciekawiłeś mnie tematem chciałbym o tym poczytać.
Nie bardzo wiem, co chciałbyś poczytać. Narzędzia core utilsowe (cat, grep, sort i tak dalej) wczytują wejście i przetwarzają na wyjście. Nie ma znaczenia, czy wejście jest z konsoli czy z pliku, bo koncepcyjnie oba wejścia są tym samym (w standardzie POSIX wszystko jest plikiem).

Przykładowo cat:
Jeżeli nie podamy pliku, to czyta ze standardowego wejścia (to jest albo konsola, albo coś podane przez pipe |)
https://github.com/coreutils/coreutils/blob/master/src/cat.c#L666

Jeżeli podamy plik, to tu jest otwierany uchwyt:
https://github.com/coreutils/coreutils/blob/master/src/cat.c#L672

Odczyt trwa dopóki coś jest w strumieniu (czyli udało się odczytać niezerową liczbę znaków):
https://github.com/coreutils/coreutils/blob/master/src/cat.c#L178

Sam odczyt jest robiony przy pomocy safe-read (z makrami do odczytu)
https://github.com/coreutils/gnulib/blob/master/lib/safe-read.c#L60

A funkcja read na samym końcu (po przejściu wszystkich warstw) jest od systemu i zwraca 0 przy końcu pliku:
https://man7.org/linux/man-pages/man2/read.2.html
Ponury123
Użytkownik
Użytkownik
Posty: 128
Rejestracja: 5 lip 2015, o 14:48
Płeć: Mężczyzna
Lokalizacja: nie wiem
Podziękował: 11 razy
Pomógł: 24 razy

Re: [C++] Zliczanie linii w tekście

Post autor: Ponury123 »

Dzięki ;)
Afish pisze: 8 gru 2020, o 12:58 Nie bardzo wiem, co chciałbyś poczytać. Narzędzia core utilsowe (cat, grep, sort i tak dalej) wczytują wejście i przetwarzają na wyjście.
Lubię sprawdzać jak ktoś daną rzecz zrealizował koncepcyjnie.
ODPOWIEDZ