Wyświetlanie wartości w innym systemie liczbowym:
#include <iostream>
int main() {
int number;
std::cout << "Podaj liczbe calkowita: ";
std::cin >> number;
std::cout << "Osemkowo: " << std::oct << number << std::endl;
std::cout << "Szesnastkowo: " << std::hex << number << std::endl;
std::cout << "Dziesietnie: " << std::dec << number << std::endl;
}
Dostosowywanie szerokości pól:
#include <iostream>
int main() {
std::cout.width(20); // Następny łańcuch danych wyświetlony na standardowym wyjściu zostanie umieszczony w polu o szerokości 20 znaków i dosunięty do prawej.
std::cout << "String.";
std::cout << "String.\n"; // Domyślnie (dosunięte do lewej krawędzi).
}
Ustawianie sposobu wyświetlania liczb:
#include <iostream>
int main() {
float number_float = 20.1000;
std::cout << "Domyslnie: " << number_float << std::endl; // Wyświetla "20.1".
std::cout.precision(2);
std::cout << "Po ustawieniu precyzji na wartosc 2 (domyslnie precyzja jest ustawiona na 6): " << number_float << std::endl; // Wyświetla "20".
std::cout.setf(std::ios_base::showpoint);
std::cout.precision(6);
std::cout << "Po ustawieniu flagi \"showpoint\" i prezycji na domyslna wartosc: " << number_float << std::endl; // Wyświetla "20.1000".
std::cout.unsetf(std::ios_base::showpoint);
std::cout << "Po usunieciu flagi \"showpoint\" (precyzja nadal na taka wartosc jak poprzednio): " << number_float << std::endl; // Wyświetla "20.1".
}
Plik nagłówkowy iomanip:
#include <iostream>
#include <iomanip>
int main() {
float number_float = 20.1001;
std::cout << std::setw(15); // Umieść dane wysłane na standardowe wyjście w polu o szerokości 15 znaków i wyrównaj do prawej.
std::cout << number_float << std::endl;
// Aktualnie powyższe wywołanie funkcji setw już nie obowiązuje.
std::cout << std::setprecision(6); // Precyzja na 6.
std::cout << number_float << std::endl; // Wyświetla "20.1001".
std::cout << std::setw(15);
std::cout << std::setfill('.'); // Wypełnia pustą przestrzeń aktualnego pola określonymi znakami.
std::cout << number_float << std::endl;
}
Podstawowa instrukcją służącą w C++ do wprowadzania danych jest cin, np.:
Tak jak C++ traktuje dane wynikowe jako strumień znakowy tak samo strumień wejściowy jest strumieniem znakowym wpływającym do programu. Obiekt cin potrafi konwertować dane wejściowe będące łańcuchem znaków z klawiatury na postać odpowiednią dla zmiennej. Nie można z klawiatury wprowadzić znaku końca łańcucha więc obiekt cin musi mieć inną metodę znajdowania jego końca. Uznaje się, że łańcuch kończy się wraz z napotkaniem białego znaku. W związku z tym cin
odczytuje tylko jedno słowo. Po jego odczytaniu automatycznie dodawany jest znak końca łańcucha jeżeli wczytywanie następuje do tablicy znakowej. Obiekt cin może być również wywoływany w postaci "cin.get(zmienna_char);", która wczytuje następny znak nawet jeżeli jest to spacja i przypisuje go zmiennej.
Przykład tego jak widoczne są dane wejściowe przy zastosowaniu cin:
#include <iostream>
#include <string>
int main() {
std::string input;
int integer;
char sign;
std::cout << "Podaj dane (tablica char, int, char oddzielone spacjami): ";
std::cin >> input >> integer >> sign;
// Jeżeli podamy dane wejściowe tak jak nas prosi program to oczywiście jest to poprawne ale jeżeli trzecia dana będzie stringiem to zostanie przeczytany tylko jeden znak, a reszta zostanie w buforze.
std::cin.clear(); // Ta funkcja zeruje stan strumienia.
std::cout << "Podaj liczby: ";
while (std::cin >> integer) {
std::cout << "Podales: " << integer << std::endl;
// Jeżeli jednak zamiast liczby całkowitej podamy np. "123Z" to program wczyta do zmiennej wartość 123 i zakończy działanie.
}
}
Jednoznakowe funkcje wejścia:
#include <iostream>
int main() {
char character;
std::cout << "Podaj dane wejsciowe (funkcja get):\n";
std::cin.get(character); // Ze względu na zastosowanie funkcji get program będzie wyświetlał zarówno znaki białe jak i drukowalne.
while (character != '\n') {
std::cout << "Podales: " << character << std::endl;
std::cout << "Podaj dane wejsciowe (funkcja get):\n";
std::cin.get(character);
}
std::cout << std::endl;
std::cout << "Podaj dane wejsciowe (obiekt cin) i zakoncz znakiem \"q\":\n";
std::cin >> character; // Użycie tej instrukcji spowoduje, iż program pominie białe znaki, a wykonywanie poniższej pętli nie zostanie nigdy przerwane jeżeli warunkiem jest przypisanie do zmiennej białego znaku.
while (character != 'q') {
std::cout << "Podales: " << character << std::endl;
std::cout << "Podaj dane wejsciowe (obiekt cin):\n";
std::cin >> character;
}
// Poniższy kod pokazuje można łączyć wywołanie funkcji get i obiektu cin:
// char character_one, character_two, character_three;
//
// std::cin.get(character_one).cin.get(character_two) >> character_three;
}
Łańcuchowe funkcje wejścia:
#include <iostream>
const int limit = 256;
int main() {
char array[limit];
char character;
std::cout << "Wprowadz lancuch znakow (funkcja get): ";
std::cin.get(array, limit, '\n'); // Ta funkcja pozostawia znak separatora w kolejce wejściowej.
std::cout << "Oto Twoje dane: " << array << std::endl;
std::cin.get(character);
std::cout << "Nastepny znak wejsciowy to: " << character << std::endl;
std::cout << "Wprowadz lancuch znakow (funkcja getline): ";
std::cin.getline(array, limit, '\n'); // Ta funkcja nie pozostawia znaku separatora w kolejce wejściowej.
std::cout << "Oto Twoje dane: " << array << std::endl;
std::cin.get(character);
std::cout << "Nastepny znak wejsciowy to: " << character << std::endl;
}
Funkcja getline (klasa istream)
wczytuje całe wiersze uznając za koniec danych znak nowego wiersza, a na końcu tablicy dodaje znak końca łańcucha, np.:
cin.getline(tablica, ilość_znaków);
Kolejną funkcją
wczytującą całe wiersze jest get (również klasa istream), np.:
cin.get(tablica, ilość_znaków);
Różnicą w stosunku do getline jest to, iż
zamiast wczytać i odrzucić znak końca wiersza, zostawia go w kolejce wejściowej. W związku z tym kolejne wywołanie w postaci "cin.get(tablica, ilość_znaków);" sprawi, że zostanie wczytany pusty łańcuch. Rozwiązaniem jest tutaj wywołanie w postaci "cin.get();" poprzedzające chęć pobrania danych z klawiatury, które "zje" znak nowego wiersza. Bezargumentowa wersja get zwraca następny znak pozyskany z wejścia programu, który można przypisać zmiennej (zwrca kod znaku, który można przypisać do typu int). Rozwiązanie problemu może mieć również postać "cin.get(tablica, ilość_znaków).get();" po czym następuje kolejne wywołanie get z argumentami.
Różnicą między getline a get jest to, że get pozwala na zachowanie większej ostrożności. Przykładowo jeżeli użyliśmy get do wczytania tablicy to skąd wiadomo, iż odczytany został cały wiersz czy też przerwano go z powodu przepełnienia tablicy. Jeżeli kolejnym znakiem wejściowym jest znak nowego wiersza to wczytano cały wiersz, a w przeciwnym wypadku nadal mamy dane do odczytania. getline jest prostsza w użyciu jednak w starszych implementacjach może w ogóle nie występować.
Jednym z
problemów jakie towarzyszą wywołaniom powyższych funkcji jest to, że w funkcje getline i get pozostawiają niewczytane znaki w kolejce wejściowej jeżeli łańcuch wejściowy jest dłuższy od miejsca na niego przeznaczonego. Poza tym jeżeli get odczyta pusty wiersz to ustawia bit błędu (co nie tyczy się getline), a dalsze wczytywanie danych jest wstrzymane aż do wywołania "cin.clear();". Problem pojawia się też kiedy wczytujemy liczbę za pomocą obiektu cin, a w kolejce wejściowej pozostaje nam znak nowego wiersza. Wyjściem z sytuacji jest oczywiście puste wywołanie "cin.get()" tudzież "(cin >> zmienna).get()".
Wejście i wyjście plikowe:
#include <iostream>
#include <fstream> // Dla klas ofstream (zapis) i ifstream (odczyt).
#include <string>
#include <exception>
int main() {
std::string filename;
std::cout << "Podaj sciezke i nazwe nowego pliku: ";
std::cin >> filename;
std::ofstream out(filename.c_str(), std::ios_base::out|std::ios_base::app); // Odczyt i dołączanie na końcu pliku.
// std::ofstream out(filename.c_str()); // W tej postaci wywołania wszystkie dane, które są w podanym pliku zostaną uprzednio wykasowane.
// Można również powyższa instrukcję zastąpić poniższymi:
// std::ofstream out;
//
// out.open(filename.c_str());
out << "Pierwsza linijka.\n";
out << "Druga linijka.\n";
out.close();
std::ifstream in(filename.c_str());
std::cout << "Oto zawartosc pliku:\n";
char character;
try {
while (in.get(character))
std::cout << character;
}
catch (std::ios::failure const & exception) {
std::cout << "Nie udalo sie przeczytac z pliku poniewaz: " << exception.what() << std::endl;
}
// Do sprawdzania możliwości otwarcia pliku można również użyć wywołania "in.is_open()", które zwraca false jeżeli nie udało się otworzyć do odczytu.
in.close();
}
Stałe trybu otwarcia pliku:
- "ios_base::in": odczyt,
- "ios_base::out": zapis,
- "ios_base::ate": ustaw się na końcu,
- "ios_base::app": dołącz na koniec pliku,
- "ios_base::trunc": usuń zawartość pliku,
- "ios_base::binary": plik binarny.
Źródło: Prata S., Język C++. Szkoła programowania, Wydanie VI, Helion SA, 2012