Lập trình C++ | Thao tác với input trong C++ (Advance)

mới xu được bên congdongcviet.com về việc nhập sai kiểu dữ liệu:http://forums.congdongcviet.com/showthread.php?t=6380

// that make basic console input easier for new C++ programmers.
//
// basic_input:
//    template<typename charT, typename traits, typename T>
//      inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
//    template<typename charT, typename traits, typename Allocator>
//      inline bool basic_input(std::basic_istream<charT,traits>& is, std::basic_string<charT,traits,Allocator>& x, charT delim)
//    template<typename charT, typename traits>
//      inline bool basic_input(std::basic_istream<charT,traits>& is, charT* x, std::streamsize count, charT delim)
//    template<typename charT, typename traits, typename T>
//      inline bool basic_input(std::basic_istream<charT,traits>& is, T& x)
//
//  Returns:
//    bool – true if the input succeeded, false otherwise.
//
//  Effects:
//    This function attempts to read from the input stream into the passed in
//    variable up to the specified delimiter. If the data in the stream does
//    not match the expected format of the variable type, or if the character
//    following the data read in is not the delimiter, then the input fails.
//
//    On success, the variable x contains the inputted value. On failure, the
//    variable x is cleared (i.e. default-initialized).
//
//    On success or failure, the input stream is left in a good state and all
//    characters up to and including the delimiter are removed from the stream.
//
//    The delimiter defaults to ‘\n’ if not specified.
//
//    If the variable type is char* (or some other character pointer), and the
//    delimiter has not yet been reached prior to count characters being read
//    in, then the input has failed and the array pointed to by the char* will
//    be filled with count characters set to null.
//
//  Sample usage:
//    int i;
//    std::cout << “Enter an int: “;
//    while (!bip::basic_input(std::cin, i))
//        std::cout << “Invalid int! Try again: “;
//
//
// ignore_line:
//    template<typename charT, typename traits>
//    inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is, charT delim)
//    template<typename charT, typename traits>
//    inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
//
//  Returns:
//    std::basic_istream<charT,traits>& – the stream passed in.
//
//  Effects:
//    This function reads and discards all characters in the passed in input
//    stream up to and including the first instance of the delimiter. The
//    delimiter defaults to ‘\n’ if not specified.
//
//  Sample usage:
//    std::cout << “Press Enter to Close.\n”;
//    bip::ignore_line(std::cin);
//

#ifndef BASIC_INPUT_H_
#define BASIC_INPUT_H_

#include <istream>
#include <ios>
#include <string>
#include <limits>

namespace bip
{
template<typename charT, typename traits>
inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is, charT delim)
{
return is.ignore(std::numeric_limits<std::streamsize>::max(), delim);
}

template<typename charT, typename traits>
inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
{
return ignore_line(is, is.widen(‘\n’));
}

template<typename charT, typename traits, typename T>
inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
{
std::ios::fmtflags old_flags = is.flags();
if ((is >> std::noskipws >> x) && (is.eof() || is.get() == delim))
{
is.flags(old_flags);
return true;
}
is.flags(old_flags);

x = T();
is.clear();
ignore_line(is, delim);
return false;
}

template<typename charT, typename traits, typename Allocator>
inline bool basic_input(std::basic_istream<charT,traits>& is, std::basic_string<charT,traits,Allocator>& x, charT delim)
{
if (std::getline(is, x, delim))
return true;

x.clear();
is.clear();
return false;
}

template<typename charT, typename traits>
inline bool basic_input(std::basic_istream<charT,traits>& is, charT* x, std::streamsize count, charT delim)
{
if (is.getline(x, count, delim))
return true;

if (is.gcount()+1 < count)
memset(x, charT(), count);

is.clear();
ignore_line(is, delim);
return false;
}

template<typename charT, typename traits, typename T>
inline bool basic_input(std::basic_istream<charT,traits>& is, T& x)
{
return basic_input(is, x, is.widen(‘\n’));
}
}
driver example
#endif  // BASIC_INPUT_H_

ví dụ:

#include <iostream>
#include <string>
#include “basic_input.h”

int main()
{
const std::streamsize cslen = 5;
char cstyle[cslen];
std::cout << “Enter a line of text: “;
if (bip::basic_input(std::cin, cstyle, cslen, ‘\n’))
std::cout << “The line of text read in was: ” << cstyle << std::endl;
else
std::cout << “Sorry, invalid: ” << cstyle << std::endl;

std::string s;
std::cout << “Enter a line of text: “;
bip::basic_input(std::cin, s);
std::cout << “The line of text read in was: ” << s << std::endl;

int i;
std::cout << “Enter an int: “;
if (bip::basic_input(std::cin, i))
std::cout << “The number read in was: ” << i << std::endl;
else
std::cout << “Sorry, invalid int!” << std::endl;

double d;
std::cout << “Enter a double: “;
while (!bip::basic_input(std::cin, d))
{
std::cout << “Invalid double! Try again: “;
}
std::cout << “The double read in was: ” << d << std::endl;

std::wstring ws;
std::wcout << L”Enter a line of text: “;
bip::basic_input(std::wcin, ws);
std::wcout << L”The line of text read in was: ” << ws << std::endl;

int wi;
std::wcout << L”Enter an int: “;
if (bip::basic_input(std::wcin, wi))
std::wcout << L”The number read in was: ” << wi << std::endl;
else
std::wcout << L”Sorry, invalid int!” << std::endl;

double wd;
std::wcout << L”Enter a double: “;
while (!bip::basic_input(std::wcin, wd))
{
std::wcout << L”Invalid double! Try again: “;
}
std::wcout << L”The double read in was: ” << wd << std::endl;

std::cout << “Press Enter to Close.\n”;
bip::ignore_line(std::cin);
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s