Chúng ta sẽ sử dụng 2 thằng ostringstream và istringstream và thao tác rất đơn giản như sau :
Convert chuỗi sang số :
convert.h
Trong ví dụ trên hàm stringify của chúng ta nhận 1 đối là x và định nghĩa toán tử xuất <<. Câu lệnh if sẽ bảo đảm rằng sự chuyển đổi thành công.PHP Code:#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
inline std::string stringify(double x)
{
std::ostringstream o;
if (!(o << x))
throw BadConversion("stringify(double)");
return o.str();
}
Thằng o.str() trả về 1 chuỗi sẽ chứa bất cứ cái gì trong stream được nhập vào, trong trường hợp này là chuỗi của giá trị x.
Driver example:
Convert số sang chuỗi :PHP Code:#include "convert.h"
void myCode()
{
double x = ...;
...
std::string s = "the value is " + stringify(x);
...
}
Cũng tương tự như trên nhưng lúc này ta sẽ dùng istringstream
Driver example :PHP Code:#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
inline double convertToDouble(const std::string& s)
{
std::istringstream i(s);
double x;
if (!(i >> x))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
Nếu kĩ hơn và để tăng performance ta có thể thêm thắt 1 chút muối tiêu vào như sau :PHP Code:#include "convert.h"
void myCode()
{
std::string s = ...a string representation of a number...;
...
double x = convertToDouble(s);
...
}
Thằng bool failIfLeftoverChars sẽ kiểm tra xem có còn kí tự nào sót lại trên bộ đếm hay không.PHP Code:inline double convertToDouble(const std::string& s,
bool failIfLeftoverChars = true)
{
std::istringstream i(s);
double x;
char c;
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
Thân !
Nhưng code ở trên vẫn còn hạn chế vì chỉ sử dụng được với 1 kiểu dữ liệu nhất định, vậy làm sao ta có thể dùng được với mọi kiểu dữ liễu. Template sẽ là giải pháp :
Driver example :PHP Code:#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
template<typename T>
inline std::string stringify(const T& x)
{
std::ostringstream o;
if (!(o << x))
throw BadConversion(std::string("stringify(")
+ typeid(x).name() + ")");
return o.str();
}
Tượng tự với kênh nhập vào cin, ta viết lại hàm convert như sau:PHP Code:#include "convert.h"
void myCode()
{
Foo x;
...
std::string s = "this is a Foo: " + stringify(x);
...
}
Driver examplePHP Code:template<typename T>
inline void convert(const std::string& s, T& x,
bool failIfLeftoverChars = true)
{
std::istringstream i(s);
char c;
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
throw BadConversion(s);
}
Và nếu chúng ta muốn có kiểu trả về để làm gì đó thì ta cũng viết lại 1 cách đơn giản như sau :PHP Code:#include "convert.h"
void myCode()
{
std::string s = ...a string representation of a Foo...;
...
Foo x;
convert(s, x);
...
...code that uses x...
}
Driver example :PHP Code:template<typename T>
inline T convertTo(const std::string& s,
bool failIfLeftoverChars = true)
{
T x;
convert(s, x, failIfLeftoverChars);
return x;
}
PHP Code:#include "convert.h"
void myCode()
{
std::string a = ...string representation of an int...;
std::string b = ...string representation of an int...;
...
if (convertTo<int>(a) < convertTo<int>(b))
...;
}