std::cin Nedir
Açıklaması şöyle.
Constructor - streambuf
istream parametre olarak verilen streambuf nesnesini sahiplenmez. Dolayısıyla streambuf nesnesi heap'te yaratılmış ise silmez. Bu durumda şöyle yaparız.
Bu sınıf en çok bir bellek alanından bir şey okumak için kullanılır. Şöyle yaparız.
Eğer streambuf olarak null vermek istersek şöyle yaparız.
Bu sınıfı kopyalamak mümkün değil. Açıklaması şöyle
Şöyle yaparız.
Tüm bitleri temizler.
goodbit : Diğer bitlerin atanmadığını, herşeyin yolunda olduğunu döner.
eofbit : End of File, yani dosya sonunun aşıldığını belirtir.
failbit : I/O işleminde hata olduğunu belirtir. Genellikle formatlama hatasıdır.
badbit : Geri dönülemez bir hata olduğunu belirtir. Stream'in dosya başından da önceye kaydırılması örnek verilebilir.
Bitleri yazdırmak için şöyle yaparız. Ancak bu bitler gerçekte bit olarak temsil edilmeyebilir. Dolayısıyla eof(), fail(), bad() metodlarını kullanmak daha iyi.
good biti
Şu açıklama bu bitin ne işe yaradığını anlatıyor.
Eğer okuma işlemi başarısız olursa failbit kaldırılır. Aynı zamanda okuma işlemi de false döner. Stream'in Boolean bir değer dönmesinin sebebi aşağıda belirtilen Boolean metodlarıdır.
std::cin içn Ctrl + Z ile eof gönderilir. Açıklaması şöyle.
Şöyle yaparız.
Şöyle yaparız.
Bu metod nedense C tipi char * alıyor. std::string ile direkt çalıştıran bir metodu yok. Aslında buffer'dan bir şey okutmak için çok kullanışlı.
Eğer stream'i kurarken verilen belleği okutmak istersek, std::getline (myistream) şeklinde kullanmak gerekir.
ignore metodu
Belirtilen karakter veya sayıya kadar veriyi es geçerek tüketir.
C++11'e kadar okuma işleminde hata olursa okuma yapılan değişken güncellenmiyordu.
operator !() metodu
fail olup olmadığını döner.
Bu metodlar sayesinde stream if ve while içinde kullanılabilir.
Okunan karakteri geri koyar. Şöyle yaparız.
Açıklaması şöyle. Dolayısıyla read() metodunu kullanmak daha iyi olabilir.
Şöyle yaparız.
sync metodu
Alttaki stream değiştiyse değişiklikleri almak için kullanılır. Şöyle yaparız.
Normalde cin ve cout birbirlerine bağlıdırlar. Yani önce cout daha sonra cin işlemi çalışır. Böylece prompt edilen metin ekranda görüldükten sonra cin işleminin çalışacağı garanti edilir. Bu metoda 0 veya NULL geçerek cin ve cout arasındaki bu bağlantı koparılabilir. Açıklaması şöyle
Örnek - Bağlantıyı koparmak
Şöyle yaparız. 0 yerine NULL da kullanılabilir.
Elimizde şöyle bir kod olsun. Bu metod istream'in bağlı olduğu Prompt stream'ini alır ve bir metin gösterir.
C++'taki stream'ler ile C metodları birlikte çalışmazlar. istream'deki veriyi okuyup C'deki FILE yapısına kopyalamak için Linux'ta fopencookie kullanılabilir.
Record Okumak
Elimizde : karakteri ile ayrılmış alanlar olsun. Şöyle yaparız.
Açıklaması şöyle.
std::cout and std::cin are global objects of classes std::ostream and std::istream respectively, which they've overloaded operator << and >>.Dolayısıyla std::istream sınıfının tüm metodlarını kullanmak mümkün.
Constructor - streambuf
istream parametre olarak verilen streambuf nesnesini sahiplenmez. Dolayısıyla streambuf nesnesi heap'te yaratılmış ise silmez. Bu durumda şöyle yaparız.
class config_istream : public std::istream {
public:
config_istream(std::string name) :
std::istream(fslib.InputStream(name.c_str()))
{
}
~config_istream() { delete rdbuf(); }
};
ÖrnekBu sınıf en çok bir bellek alanından bir şey okumak için kullanılır. Şöyle yaparız.
#include <iostream>
#include <istream>
#include <streambuf>
#include <string>
struct membuf : std::streambuf
{
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};
int main()
{
char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";
membuf sbuf(buffer, buffer + sizeof(buffer));
std::istream in(&sbuf);
std::string line;
while (std::getline(in, line)) {
std::cout << "line: " << line << "\n";
}
return 0;
}
Aynı iş için istringstream'i kullanmak çok daha kolay.std::string a = "abc..";
std::istringstream istr (a);
ÖrnekEğer streambuf olarak null vermek istersek şöyle yaparız.
std::istream in(0);
copy - constructorBu sınıfı kopyalamak mümkün değil. Açıklaması şöyle
bad metoduAn istream object, for example, represents a stream of input values, some of which may have already been read, and some of which will potentially be read later. If an istream were to be copied, would that entail copying all the values that had already been read as well as all the values that would be read in the future? The easiest way to deal with such questions is to define them out of existence. Prohibiting the copying of streams does just that
Şöyle yaparız.
std::istream is = ...
std::cout << "is.bad(): " << is.bad();
clear metoduTüm bitleri temizler.
goodbit : Diğer bitlerin atanmadığını, herşeyin yolunda olduğunu döner.
eofbit : End of File, yani dosya sonunun aşıldığını belirtir.
failbit : I/O işleminde hata olduğunu belirtir. Genellikle formatlama hatasıdır.
badbit : Geri dönülemez bir hata olduğunu belirtir. Stream'in dosya başından da önceye kaydırılması örnek verilebilir.
Bitleri yazdırmak için şöyle yaparız. Ancak bu bitler gerçekte bit olarak temsil edilmeyebilir. Dolayısıyla eof(), fail(), bad() metodlarını kullanmak daha iyi.
istream is = ...;
cout << is.eofbit << " " << is.failbit << " " << is.badbit << endl;
Şimdi bitlerin nasıl kullanıldığına bakalımgood biti
Şu açıklama bu bitin ne işe yaradığını anlatıyor.
failbit bitigood() returns 0 if it has a problem reading from the file, file not existing, etc
Eğer okuma işlemi başarısız olursa failbit kaldırılır. Aynı zamanda okuma işlemi de false döner. Stream'in Boolean bir değer dönmesinin sebebi aşağıda belirtilen Boolean metodlarıdır.
do {
std::cout << "Enter the employee ID: ";
} while(!(std::cin >> e.id));
failbit şöyle kontrol edilir ve temizlenir.if (!std::cin) {
std::cin.clear();
...
}
Sadece belli bir biti temizlemek istersek şöyle yaparız.std::cin.clear(std::cin.rdstate() & ~std::ios::failbit);
eof metodustd::cin içn Ctrl + Z ile eof gönderilir. Açıklaması şöyle.
The end-of-file character (CTRL-Z on the keyboard) sets the internal state flag of std::cin to eofbit, which must be cleared with basic_ios::clear() before following calls to getline will work properly.Örnek
.
Şöyle yaparız.
std::istream is = ...
std::cout << "is.eof(): " << is.eof();
fail metodu
Okuma işlemine verilen tip ile veri uyuşmazsa fail() eder. fail etmiş stream'i kurtarmak için genellikle girdi temizlenir. Yani şöyle yapılır.std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
ÖrnekŞöyle yaparız.
std::istream is = ...
std::cout << "is.fail(): " << is.fail();
Örnek
Şöyle yaparız.
Şöyle yaparız.
Şöyle yaparız.Şöyle yaparız.
int letter = 0;
while (1) {
std::cout << "Please type in a number: ";
std::cin >> letter;
if (std::cin.eof()) {
std::cout << std::endl;
return 1;
} else if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout <<"Integer input required. Try again.\n";
} else if (letter < 1 || letter > 26) {
std::cout <<"The English alphabet only has 26 letters. Try again.\n";
} else {
break;
}
}
gcount metoduŞöyle yaparız.
std::size_t read_size = is.gcount();
get metoduchar c;
cin.get (c);
Döngü içinde kullanmak için şöyle yaparız.while(std::cin.get(c)) {...}
cin ile binary veri okumak mümkün değil. Örneğin Binary veri içinde Ctrl + Z'ye denk geliyorsa, bunu durma karakteri olarak algılar. Windows'ta cin'i binary mod'a geçirmek için şöyle yaparız._setmode(_fileno(stdin), _O_BINARY);
cin.read(...);
getline metoduBu metod nedense C tipi char * alıyor. std::string ile direkt çalıştıran bir metodu yok. Aslında buffer'dan bir şey okutmak için çok kullanışlı.
Eğer stream'i kurarken verilen belleği okutmak istersek, std::getline (myistream) şeklinde kullanmak gerekir.
ignore metodu
Belirtilen karakter veya sayıya kadar veriyi es geçerek tüketir.
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Özellikle menü sunan konsol programlarında satır sonuna kadar okuma için kullanılabilir. Beklenen değer okunduktan sonra geriye kalan tüm boşlukları dikkate almaz. Burada ignore() metodunun kullanıldığı görülebilir.template <typename T>
T easy_input( std::istream& is = std::cin )
{
T value{};
is >> value;
is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
return value;
}
Okunan değeri bir predicate ile kontrol etmek için şöyle yaparız.template <typename T, typename Predicate>
T easy_input( Predicate pred, std::istream& is = std::cin )
{
T value{};
while ( !pred( value = easy_input<T>() ) ) //yukarıdaki easy_input'u kullanır
{}
return value;
}
Bu metodu şöyle kullanırız.int value = easy_input<int>( [] ( int i ) { return i >= 0 && i <= 10; } );
operator >> metoduC++11'e kadar okuma işleminde hata olursa okuma yapılan değişken güncellenmiyordu.
C++11'den sonra ile okumada hata olması durumunda, değeri saklayan değişkene 0 yazılmaya başlandı. Örnekte a girdisi verirsek - hatalı bir girdi - x'in değeri 0 olur.If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
#include <iostream>
int main()
{
int x = 5;
std::cin >> x;
std::cout << x << '\n';
}
Örnek
Elimizde >> operator'ünü sağlamayan bir sınıf olsun. Şöyle yaparız.
!fail olup olmadığını döner.Elimizde >> operator'ünü sağlamayan bir sınıf olsun. Şöyle yaparız.
SalesItem book;
std::cin >> book ;
Bu durumda şu hatayı alırız.error: no match for 'operator>>' (operand types are 'std::istream
{aka std::basic_istream<char>}' and 'Sales_item')
Sınıfa operator>> metodunu eklemek için şöyle yaparız.class SalesItem {
std::string m_item_name;
int m_itemno;
public:
friend std::istream& operator>>(std::istream& o,Sales_item& obj) {
o>>obj.m_item_name>>obj.m_itemno;
return o;
}
friend std::ostream& operator<<(std::ostream& o,const Sales_item& obj) {
o<<obj.m_item_name<<' '<<obj.m_itemno;
return o;
}
};
operator void* metoduoperator !() metodu
fail olup olmadığını döner.
Bu metodlar sayesinde stream if ve while içinde kullanılabilir.
if (stream >> x)
{
}
while(stream)
{
/* do Stuff */
}
peek metodu
Örnek
Şöyle yaparız.
Şöyle yaparız.
Şöyle yaparız.
Herhangi bir istream akımını unbuffered hale getirmek için şöyle yapılır.Örnek
Şöyle yaparız.
// Skip all white space
while (std::isspace(std::cin.peek()))
std::cin.get();
ÖrnekŞöyle yaparız.
std::istream& eat_whitespace(std::istream &is) // eats whitespace except '\n'
{
int ch;
while (is && (ch = is.peek()) != EOF && ch != '\n'
&& std::isspace(static_cast<char unsigned>(ch)))
{
is.get();
}
return is;
}
read metoduŞöyle yaparız.
std::size_t const buf_size = 256;
char buf[buf_size] = { '\0' };
is.read(buf, buf_size);
rdbuf metodustd::ifstream in;
in.rdbuf()->pubsetbuf(0, 0);
in.open("/dev/random");
putback metoduOkunan karakteri geri koyar. Şöyle yaparız.
std::istream in = ...;
char c, d;
in >> c >> d;
if (c == d) {
in.putback(d);
in.putback(c);
}
readsome metoduAçıklaması şöyle. Dolayısıyla read() metodunu kullanmak daha iyi olabilir.
The behavior of this function is highly implementation-specific. For example, when used with std::ifstream, some library implementations fill the underlying filebuf with data as soon as the file is opened (and readsome() on such implementations reads data, potentially, but not necessarily, the entire file), while other implementations only read from file when an actual input operation is requested (and readsome() issued after file opening never extracts any characters). Likewise, a call to std::cin.readsome() may return all pending unprocessed console input, or may always return zero and extract no characters.Şöyle yaparız.
char c[1024] = {};
std::streamsize num = std::cin.readsome(c, 1023);
rdstate metoduŞöyle yaparız.
istream &is = ...
cout << is.rdstate() << endl;
setstate metodu
Bir biti elle atamak istersek şöyle yaparız.
in.setstate (std::ios_base::failbit);
Alttaki stream değiştiyse değişiklikleri almak için kullanılır. Şöyle yaparız.
is.sync();
tie metodu - istream Sınıfına Bağlı ostream Nesnesini DönerNormalde cin ve cout birbirlerine bağlıdırlar. Yani önce cout daha sonra cin işlemi çalışır. Böylece prompt edilen metin ekranda görüldükten sonra cin işleminin çalışacağı garanti edilir. Bu metoda 0 veya NULL geçerek cin ve cout arasındaki bu bağlantı koparılabilir. Açıklaması şöyle
If cin and cout are tied, you can expect the output to be flushed (i.e., visible on the console) before the program prompts input from the user. If you untie the streams, the program might block waiting for the user to enter their name but the "Enter name" message is not yet visible (because cout is buffered by default, output is flushed/displayed on the console only on demand or when the buffer is full).Her stream tie() sonucunda bir şey döndürmüyor.
So if you untie cin from cout, you must make sure to flush cout manually every time you want to display something before expecting input on cin.
In conclusion, know what each of them does, understand the consequences, and then decide if you really want or need the possible side effect of speed improvement.
Örnek - Bağlantıyı koparmak
Şöyle yaparız. 0 yerine NULL da kullanılabilir.
cin.tie(0);
Şöyle yaparızcin.tie(NULL);
ÖrnekElimizde şöyle bir kod olsun. Bu metod istream'in bağlı olduğu Prompt stream'ini alır ve bir metin gösterir.
namespace stdex // not std namespace
{
template <typename Input, typename Prompt>
Input easy_input(const Prompt& prompt,std::istream& in = std::cin)
{
auto user_input_value = Input{}; // initialize value on creation
auto tied_stream = in.tie();
if(tied_stream)
(*tied_stream) << prompt;
if(!(in >> user_input_value))
throw std::runtime_error{ "easy_input: Bad input" }; // handle errors
return user_input_value;
}
}
Bu metod verilen stream'e göre Prompt etmeli. Aşağıdaki kodda istringstream bir outputstream'e bağlı olmadığı için prompt çalışmaz.auto a = stdex::easy_input<std::string>("name: ");
std::istringstream in{ "aaa bbb" };
auto b = stdex::easy_input<std::string>(">> ", in); // will not prompt
Şu kodda ise çalışır.std::istringstream in{ "aaa bbb" };
std::ostringstream out;
in.tie(&out);
auto c = stdex::easy_input<std::string>(">> ", in);
assert(">> " == out.str());
DiğerC++'taki stream'ler ile C metodları birlikte çalışmazlar. istream'deki veriyi okuyup C'deki FILE yapısına kopyalamak için Linux'ta fopencookie kullanılabilir.
Record Okumak
Elimizde : karakteri ile ayrılmış alanlar olsun. Şöyle yaparız.
struct expect
{
char c;
expect( char c ): c(c) { }
};
std::istream& operator >> ( std::istream& ins, const expect& c )
{
ins >> std::ws;
if (ins.peek() == c.c)
ins.get();
else
ins.setstate( std::ios::failbit );
return ins;
}
std::istream& operator >> ( std::istream& ins, Mammal& mammal )
{
return ins
>> mammal.species
>> mammal.dateOfBirth.month >> expect( ':' )
>> mammal.dateOfBirth.day >> expect( ':' )
>> mammal.dateOfBirth.year
>> mammal.weight
>> mammal.enclosureSize.length >> expect( ':' )
>> mammal.enclosureSize.width >> expect( ':' )
>> mammal.enclosureSize.height
>> mammal.exhibit;
}
Çağırmak için şöyle yaparız.std::vector <Mammal> mammals;
int num_mammals;
std::cin >> num_mammals;
Mammal mammal;
while (std::cin >> mammal)
mammals.push_back( mammal );
Hiç yorum yok:
Yorum Gönder