Strona 1 z 1

[C++] Zliczanie linii w tekście

: 6 gru 2020, o 19:33
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;
}

Re: String c++.

: 6 gru 2020, o 20:42
autor: Dasio11
Polecenie jest nieprecyzyjne - skoro możliwe ma być wpisanie wielu linii, to skąd program ma wiedzieć, kiedy tekst się kończy?

Re: String c++.

: 7 gru 2020, o 08:05
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".

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

: 7 gru 2020, o 10:00
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?

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

: 7 gru 2020, o 10:24
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.

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

: 7 gru 2020, o 11:47
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.

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

: 7 gru 2020, o 12:10
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.

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

: 7 gru 2020, o 21:45
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.

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

: 7 gru 2020, o 22:12
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ś.

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

: 8 gru 2020, o 12:11
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 ;)

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

: 8 gru 2020, o 12:58
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

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

: 8 gru 2020, o 13:02
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.