c++stringstream(古くて使いやすい)
8841 ワード
前言:
以前stringstreamというクラスに触れたことがないとき、よく使われる文字列とデジタル変換関数はsscanfとsprintf関数です.最初はこの2つの関数がくわえられていると思っていましたが、結局cに属しています.c++にはストリームの概念が導入され,ストリームによる文字列と数字の変換が容易になった.ここでは、前のことをまとめて、新学を紹介します.
一般的な書式列:
%%%はパーセント記号を印刷し、変換しません.%c整数は対応するASCII文字に変換されます.%d整数は10進位に回転する.%f倍精度数字を浮動小数点数に変換します.%o整数は8進位に変換されます.%s整数は文字列に変換されます.%x整数は小文字16進位に変換されます.%X整数を大文字16進位に変換します.%n sscanf(str,"%d%n",&dig,&n),%nは、合計何ビットの文字を変換したかを表す
sprintf関数
sprintf関数のプロトタイプはint sprintf(char*str,const char*format,...)である.文字列をフォーマットします.具体的な機能は次のとおりです.
(1)数値変数を文字列に変換する.
(2)整数変数の16進数と8進数文字列を得る.
(3)複数の文字列を接続する.
sscanf関数
sscanf関数のプロトタイプはint sscanf(const char*str,const char*format,...)です.パラメータstrの文字列をパラメータformat文字列に基づいてデータを変換してフォーマットし、変換後の結果を対応するパラメータ内に保存します.具体的な機能は以下の通りです.
(1)フォーマットに従って文字列からデータを抽出する.整数、浮動小数点数、文字列などを文字列から取り出す.
(2)指定された長さの文字列をとる
(3)指定文字までとる文字列
(4)指定した文字セットのみを含む文字列をとる
(5)指定した文字セットまで取った文字列
もちろん、sscanfはフォーマット列「%[]」形式をサポートすることができ、興味のあることは検討することができます.
出力結果:123.432 432 11、すなわち11ビットの文字が変換された.
stringstreamクラス:
ライブラリは、istringstream、ostringstream、stringstreamの3種類を定義し、それぞれストリームの入出力操作に使用されます.
1.stringstream::str(); returns a string object with a copy of the current contents of the stream.
2.stringstream::str (const string& s); sets s as the contents of the stream, discarding any previous contents.
3.stringstreamクリア、stringstream s;s.str("");
4.任意のタイプの変換を実現
template out_type convert(const in_value&t){stringstream stream;stream<>result;//resultに値return resultを書き込む;}
出力:1 1 23 23#0 4
ちなみに、今日もstringstreamというクラスを使って、ツリーのシーケンス化と逆シーケンス化をしました.
タイトルリンク:http://www.lintcode.com/zh-cn/problem/binary-tree-serialization/
ツリーのシーケンス化と逆シーケンス化
アルゴリズムを設計し,コードを記述して二叉木をシーケンス化し,逆シーケンス化する.ツリーを1つのファイルに書き込むことを「シーケンス化」と呼び、ファイルを読み込んで同じツリーを再構築することを「逆シーケンス化」と呼ぶ.ツリーを逆シーケンス化またはシーケンス化する方法には制限はありません.ツリーを文字列にシーケンス化し、文字列を元のツリー構造に逆シーケンス化できることを確認する必要があります.
考え方:
二叉木のシーケンス化は、空のサブツリーが'#'で表される順に巡回することによって確立される.逆シーケンス化の場合は、'#'に遭遇すると再帰構造が停止します.またシーケンス化の場合は整数をstringstreamで文字列に変換し,逆シーケンス化は文字列をstringstreamで整数に変換する.
以前stringstreamというクラスに触れたことがないとき、よく使われる文字列とデジタル変換関数はsscanfとsprintf関数です.最初はこの2つの関数がくわえられていると思っていましたが、結局cに属しています.c++にはストリームの概念が導入され,ストリームによる文字列と数字の変換が容易になった.ここでは、前のことをまとめて、新学を紹介します.
一般的な書式列:
%%%はパーセント記号を印刷し、変換しません.%c整数は対応するASCII文字に変換されます.%d整数は10進位に回転する.%f倍精度数字を浮動小数点数に変換します.%o整数は8進位に変換されます.%s整数は文字列に変換されます.%x整数は小文字16進位に変換されます.%X整数を大文字16進位に変換します.%n sscanf(str,"%d%n",&dig,&n),%nは、合計何ビットの文字を変換したかを表す
sprintf関数
sprintf関数のプロトタイプはint sprintf(char*str,const char*format,...)である.文字列をフォーマットします.具体的な機能は次のとおりです.
(1)数値変数を文字列に変換する.
(2)整数変数の16進数と8進数文字列を得る.
(3)複数の文字列を接続する.
int main(){
char str[256] = { 0 };
int data = 1024;
// data
sprintf(str,"%d",data);
// data
sprintf(str,"0x%X",data);
// data
sprintf(str,"0%o",data);
const char *s1 = "Hello";
const char *s2 = "World";
// s1 s2
sprintf(str,"%s %s",s1,s2);
cout<<str<<endl;
return 0;
}
sscanf関数
sscanf関数のプロトタイプはint sscanf(const char*str,const char*format,...)です.パラメータstrの文字列をパラメータformat文字列に基づいてデータを変換してフォーマットし、変換後の結果を対応するパラメータ内に保存します.具体的な機能は以下の通りです.
(1)フォーマットに従って文字列からデータを抽出する.整数、浮動小数点数、文字列などを文字列から取り出す.
(2)指定された長さの文字列をとる
(3)指定文字までとる文字列
(4)指定した文字セットのみを含む文字列をとる
(5)指定した文字セットまで取った文字列
もちろん、sscanfはフォーマット列「%[]」形式をサポートすることができ、興味のあることは検討することができます.
int main(){
char s[15] = "123.432,432";
int n;
double f1;
int f2;
sscanf(s, "%lf,%d%n", &f1, &f2, &n);
cout<<f1<<" "<<f2<<" "<<n;
return 0;
}
出力結果:123.432 432 11、すなわち11ビットの文字が変換された.
stringstreamクラス:
1.stringstream::str(); returns a string object with a copy of the current contents of the stream.
2.stringstream::str (const string& s); sets s as the contents of the stream, discarding any previous contents.
3.stringstreamクリア、stringstream s;s.str("");
4.任意のタイプの変換を実現
template
int main(){
string s = "1 23 # 4";
stringstream ss;
ss<<s;
while(ss>>s){
cout<<s<<endl;
int val = convert<int>(s);
cout<<val<<endl;
}
return 0;
}
出力:1 1 23 23#0 4
ちなみに、今日もstringstreamというクラスを使って、ツリーのシーケンス化と逆シーケンス化をしました.
タイトルリンク:http://www.lintcode.com/zh-cn/problem/binary-tree-serialization/
ツリーのシーケンス化と逆シーケンス化
アルゴリズムを設計し,コードを記述して二叉木をシーケンス化し,逆シーケンス化する.ツリーを1つのファイルに書き込むことを「シーケンス化」と呼び、ファイルを読み込んで同じツリーを再構築することを「逆シーケンス化」と呼ぶ.ツリーを逆シーケンス化またはシーケンス化する方法には制限はありません.ツリーを文字列にシーケンス化し、文字列を元のツリー構造に逆シーケンス化できることを確認する必要があります.
考え方:
二叉木のシーケンス化は、空のサブツリーが'#'で表される順に巡回することによって確立される.逆シーケンス化の場合は、'#'に遭遇すると再帰構造が停止します.またシーケンス化の場合は整数をstringstreamで文字列に変換し,逆シーケンス化は文字列をstringstreamで整数に変換する.
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* This method will be invoked first, you should design your own algorithm
* to serialize a binary tree which denote by a root node to a string which
* can be easily deserialized by your own "deserialize" method later.
*/
bool first;
template<typename out_type, typename in_value>
out_type convert(const in_value & t){
stringstream stream;
stream<<t;//
out_type result;//
stream>>result;// result
return result;
}
void pre_order(TreeNode *root, string &s){
if(root){
string tmp = convert<string>(root->val);
if(!first)
s+= " "+tmp;
else {
first = false;
s+=tmp;
}
pre_order(root->left, s);
pre_order(root->right, s);
} else {
if(first)
s+='#';
else {
first = false;
s+=" #";
}
}
}
string serialize(TreeNode *root) {
// write your code here
string s="";
first = true;
pre_order(root, s);//
return s;
}
stringstream ss;
void buildT(TreeNode * &T){
string s;
ss>>s;
if(s == "#") return ;
int val = convert<int>(s);
T = new TreeNode(val);
buildT(T->left);
buildT(T->right);
}
/**
* This method will be invoked second, the argument data is what exactly
* you serialized at method "serialize", that means the data is not given by
* system, it's given by your own serialize method. So the format of data is
* designed by yourself, and deserialize it here as you serialize it in
* "serialize" method.
*/
TreeNode *deserialize(string data) {
// write your code here
TreeNode *T = NULL;
ss.str("");
ss<<data;
buildT(T);
return T;
}
};