3 teksty w 3 linijkach

Uczę się C++ i po przeczytaniu 1 działu książki jest ćwiczenie " Napisz program wyświetlający w konsoli trzy linijki tekstu i oczekując na dowolny klawisz po każdej z nich"

I wyszło mi takie coś:

#include

#include


using namespace std;


int main()

{

    cout << " Pierwsza linijka tekstu " ;

    getch();

    cout << " Druga linijka tekstu " ;

    getch();

    cout << "trzecia linijka tekstu: " ;

    getch();

    return 0;

}

Wszystko pięknie tylko że tekst pojawia się w jednej linijce . Co źle zrobiłem?

Spróbuj tak

#include

#include


using namespace std;


int main()

{

    std::cout << " Pierwsza linijka tekstu " ;

    std:: cout << " Druga linijka tekstu " ;

    std::cout << "trzecia linijka tekstu: " ;

    getch();

}

Jaka to jest książka?

Kod kalamita prawie nic nie zmienia poza tym, że nie trzeba naciskac enter przed wyswietleniem drugiej i trzeciej linijki.

Polecam przeczytać jeszcze raz ten rozdział.

#include

#include


using namespace std;


int main()

{

    cout << " Pierwsza linijka tekstu \n" ;

    getch();

    cout << " Druga linijka tekstu \n" ;

    getch();

    cout << "trzecia linijka tekstu: \n" ;

    getch();

    return 0;

}

\n-- newline

funkcja getch() nie jest kompatybilna z cout.

getch(),getche(),puts(),scanf(),printf() - zapis i odczyt synchroniczny

cout,cin,getchar() - zapis i odczyt asynchroniczne.

Zamiast getch() użyj getchar() lub cin.get(), albo zamiast cout użyj puts lub printf.

Niech na razie używa to co dali mu w książce :slight_smile: Potem sam zacznie używać czego innego :slight_smile:

Są dwa sposoby na przeniesienie do nowej linii :slight_smile:

Pierwszy sposób: jest to użycie \n, czyli znaku nowej linii (New Line). Stosuje się go tylko w cudzysłowach, czyli: jeśli chcesz w stawić linię po jakimś tekście itp. To wpisujesz:

cout<<"Pierwszy tekst\nDrugi tekst";

Co spowoduje wyświetlenie na ekranie:

Pierwszy tekst

Drugi tekst

Drugi sposób: jest to użycie endl, czyli zakończenia linii (End Line). Robi dokładnie to samo, lecz inaczej się go stosuje. Nie wstawia się go w cudzysłowach ale po za nimi. Używa go się w następujący sposób:

cout<<"Pierwszy tekst"<

Wyświetli dokładnie to samo co wyżej. Różni się tylko kodem :slight_smile:

@up, “\n” i std::endl to nie jest dokładnie to samo. std::endl to znak nowej linii dla danego systemu(Windows -"\r\n", Linux - “\n”, Mac Os - “\n\r” albo “\r” nie pamiętam już), “\n” to tylko znak nowej linii.

Tu się mylisz. Pod windows endl zdefiniowane następująco:

ostream &endl(ostream &s)

  {

   return s<<'\n'<
  }

Czyli samo ‘\n’.

A byłem święcie przekonany, że komisja standaryzująca uwzględniła to, no cóż, następnym razem sprawdzę zanim coś palne.

Przecież nic sie nie stało :wink: Każdy może się pomylić :slight_smile: Napisałem tak bo tak się nauczyłem :slight_smile:

Heh, ciekawostka, postanowiłem sprawdzić jak to jest na linux’ie z tym endl i \n.

Aby to sprawdzić napisałem sobie mikro programik:

#include 

#include 

#include 


using namespace std;


int main()

  {

   fstream f;

   f.open("./tt.dat",ios::out|ios::binary); //otwieramy plik

   f<
   f.close(); //zamykamy plik

   f.open("./tt.dat",ios::in|ios::binary); // otwieramy ponownie

   while(true)

     {

      char ch;

      f.read(&ch,1); // wczytujemy znak

      if(!f) break; // koniec jeżeli odczyt się nie udał

      cout<
     }

   f.close(); // zamykamy plik

   return 0;

  }

Odpalcie pod unix’em to się zdziwicie. Fiolek , gwarantuję kompletne zaskoczenie! :lol: Jeżeli ktoś ma Mac Os to bardzo proszę to wyprobować i dać znać co wyszło.

Czemu wynik miałby wywoływać zdziwienie? U mnie (GNU/Linux, GCC 4.3) wynik to 0xA, czyli 10, czyli znak nowej linii (Line Feed) w ASCII. I to wynik ten sam niezależnie od ustawionego trybu ios::binary.

Natomiast co do \r i \n to jest to zagadnienie wyjaśnione w Symfonii C++, różne systemy mają różne “końce linii” w plikach tekstowych. W edytorze który używam (Kate) jest do wybory nowa linia w stylu UNIX, Mac i Windows, sprawdzę co Kate wstawia w każdym ustawieniu.

Jeszcze dodam implementację std::endl w GCC 4.3 (niezbyt piękny kod, ale można się połapać co robi i jest odpowiednikiem tego co napisał 13tySmok)

template

    inline basic_ostream<_CharT, _Traits>& 

    endl(basic_ostream<_CharT, _Traits>& __os)

    { return flush(__os.put(__os.widen('\n'))); }

Jakoś mnie bardzo nie zaskoczyło :wink: ‘\n’ jako liczba, ot co.

Dla ciekawskich, endl w Visual C++ 2008:

template
	class _Traits> inline

	basic_ostream<_Elem, _Traits>&

		__CLRCALL_OR_CDECL endl(basic_ostream<_Elem, _Traits>& _Ostr)

	{	// insert newline and flush stream

	_Ostr.put(_Ostr.widen('\n'));

	_Ostr.flush();

	return (_Ostr);

	}

Sprawdziłem w Kate i nowa linia to odpowiednio:

UNIX - \n

Mac - \r

Windows - \r\n

W Symfonii autor pisze, że przy używaniu trybu tekstowego dla strumieni (czyli bez ios::binary) \n jest w Windows zamieniany na \r\n przy zapisie i na odwrót przy odczycie. To już sobie trzeba sprawdzić samemu, to jest pewnie zachowanie zależne od implementacji. Na Mac OS zapewne \n jest zamieniane na \r w trybie tekstowym (jeżeli w Windows jest zamieniane to w Mac OS chyba też powinno być). Ma ktoś dokument standardu C++ i może to sprawdzić?

PS. W ogóle wie ktoś skąd wziąć oficjalną dokumentację C++? Kiedyś szukałem i z tego co pamiętam to kosztuje $18. Czyli nie jest dostępna bezpłatnie?

Nigdy nie znalazłem w internecie za darmo dokumentacji :wink: Po 80 zł jeżeli już :stuck_out_tongue:

‘\n’==10 && ‘\n’==0xA

‘\r’==13 && ‘\r’==0xD

Wcale się nie zdziwię jeżeli na Mac Os też będzie A czyli ‘\n’

Co do kodu funkcji endl to go uprościłem aby był nieco bardziej zrozumiały:

wrzucanie znaku ‘\n’ oraz opróżnienie buforu.