无法使用 stringstream C++ 将 char 转换为字符串
Can't convert char to string with stringstream C++
我只是要警告大家,我的代码包含少量法语和英语,所以如果您不理解变量或其他内容,请务必询问并将其视为免费法语 class 哈哈。好吧,我有一个项目,其中包括为学校使用创建一个时间表,我负责管理 "time" 部分,即为教授创造时间间隔和空间来完成他们的 classes。为了确保所有情况都能正常工作,我需要确保 2 classes 不会在同一时间和地点发生。在我的函数 "rajoutcours" 中,法语中的意思是 "AddsClass",我接受了几个参数:
- 材料=主题
- heure_deb = 开始时间
- heure_fin = 结束时间
- date = 嗯,这是 class
的日期
- salle = 房间。
在我的函数中,我创建了 3 个变量,它们是 heure_start(另一个 class 开始的时间),heure_end(另一个 class 结束的时间),日期和房间(其他 class 事件发生的日期和它们发生的房间)。我使用字符串运算符“+”属性 填写这些变量,我将 txt 文件(其他 classes)中行的每个字符转换为 1 个字母的字符串,以便我可以添加它们使用 sstream 库。奇怪的是,只有一个字符被转换为字符串,而其他字符却没有,我真的不明白为什么。
无论如何,我对此了解很多,但我已经尝试找出问题好几天了,但我看不出问题出在哪里。谢谢大家的帮助。
void Utilisateur::rajout_cours(string matiere, string heure_deb, string heure_fin, string date, string salle )
{
ifstream user_in ("Cours.txt"); // txt file where classes are listed
ofstream user_out;
user_out.open("Cours.txt", ofstream::out | ofstream::app);
user_out; //write
string ligne; //line variable which reads the lines of the txt file
string heure_start; // time at which the class starts
string heure_end; // time at which the class ends
string day; // self explanatory
string room; // ie before
int i=0;
int j=0;
int cptr=0;
int a,b,c,d;
stringstream ss; // this is supposed to convert char into string
while (getline(user_in,ligne))
{
for(i=0;i<ligne.size();i++)
{
if(ligne.at(i)=='$' && cptr==0)
{
a=i;
cptr++;
cout << "Premier '$'" << endl; // Keep in mind that the '$' is the delimiter when i write on the txt file, it's also a way to know where I am.
for(j=0;j<a;j++)
{
char tmpc='[=10=]';
string tmps;
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
heure_start=heure_start+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==1)
{
b=i;
cptr++;
cout << "Deuxieme '$'" << endl;
for(j=a+1;j<(b);j++)
{
char tmpc = '[=10=]';
string tmps;
tmpc=ligne.at(j);
ss << tmpc;// conversion char en string
cout << "Lettre char a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;// conversion complète à priori
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
heure_end=heure_end+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==2)
{
c=i;
cptr++;
cout << "3eme '$'" << endl;
for(j=b+1;j<(c);j++)
{
char tmpc='[=10=]';
string tmps="";
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
room=room+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==3)
{
d=i;
cptr++;
cout << "4eme '$'" << endl;
for(j=c+1;j<(d);j++)
{
char tmpc='[=10=]';
string tmps="";
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre char a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
day=day+tmps;
}
}
}
}
if(heure_deb==heure_start && heure_fin==heure_end && date==day && salle==room) // I make sure here that the class I'm writing isn't already written in the file and in that case we leave the program.
{
cout << "Impossible d'ajouter un cours ! Un cours de " << matiere <<"a deja lieu à ce moment! Changez d'horaires ou de salles. " << endl;
exit(1);
}
cout <<"ecris" << endl;
user_out << heure_deb << "$"<< heure_fin << "$" << salle << "$" << date << "$" << matiere << endl; // If not, write the new class.
}
我已经提到过将 char
转换为 std::string
非常简单,只需使用 resp.构造函数 std::string::string(size_t count, char ch)
:
char c = 'A';
std::string str(1, c); // constructs a string str with one character
然而,在我第三次阅读这个问题后,我意识到它实际上应该按照 OP 尝试的方式工作。
所以,对我来说,实际的问题是:
为什么std::stringstream
不能重复交替使用output/input?
过了一会儿,我想起了stringstream
中的"stream"。
嗯,它可以——考虑到在用输出填充它(例如 <<
)并用输入清空它(例如 >>
)之后,它的内部状态变为 eof
,其中下一次读取将导致 fail
状态。所以,(虽然我仍然会推荐使用我上面描述的更简单的方法),
- 要么在重新使用之前重置
std::stringstream
的状态(std::stringstream::clear()
对此有好处。)
- 或者只使用
std::stringstream
的本地实例(通过将 stringstream 的构造和 input/output 语句括在一对额外的大括号 { }
中)
一个小例子:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
{ // "recycle" one instance of std::stringstream
std::stringstream sstr;
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
sstr << c;
std::string str;
sstr >> str;
std::cout << "str: '" << str << "', "
<< "sstr.good(): " << sstr.good() << ", "
<< "sstr.eof(): " << sstr.eof() << '\n';
sstr.clear();
}
}
{ // one instance per I/O
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
std::stringstream sstr;
sstr << c;
std::string str;
sstr >> str;
std::cout << "str: '" << str << "'\n";
}
}
// done
return 0;
}
输出:
c: 'A', str: 'A', sstr.good(): 0, sstr.eof(): 1
c: 'B', str: 'B', sstr.good(): 0, sstr.eof(): 1
c: 'C', str: 'C', sstr.good(): 0, sstr.eof(): 1
c: 'A', str: 'A'
c: 'B', str: 'B'
c: 'C', str: 'C'
三思后,我意识到在这种特定情况下必须清除 eof
状态还有另一个原因:
- 输出正好是一个
char
- 输入试图填充
std::string
(这在某种程度上更贪婪)并读取直到分隔符或文件结尾(并且总是后者发生)。
检查过这个:
#include <iostream>
#include <sstream>
int main()
{
// "recycle" one instance of std::stringstream
std::stringstream sstr;
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
sstr << c;
char cIO;
if (sstr >> cIO) std::cout << "cIO: '" << cIO << "'\n";
else std::cout << "reading cIO failed\n";
}
// done
return 0;
}
输出:
c: 'A', cIO: 'A'
c: 'B', cIO: 'B'
c: 'C', cIO: 'C'
现在,即使没有 sstr.clear()
它也能正常工作,因为它从不尝试读取文件末尾(又名字符串流)。
提到 "greedy" 阅读 operator>>(std::stringstream&, std::string)
让我想到了另一个想法:
如果任务中的 char
是分隔符会怎样?
#include <iostream>
#include <sstream>
#include <string>
int main()
{
char c = ' ';
std::stringstream sstr;
sstr << c;
std::cout << "c: '" << c << "', ";
std::string str;
sstr >> str;
std::cout << "str: '" << str << "'\n";
std::cout
<< "sstr.good(): " << sstr.good() << '\n'
<< "sstr.eof(): " << sstr.eof() << '\n'
<< "sstr.fail(): " << sstr.fail() << '\n'
<< "sstr.bad(): " << sstr.bad() << '\n';
// done
return 0;
}
输出:
c: ' ', str: ''
sstr.good(): 0
sstr.eof(): 1
sstr.fail(): 1
sstr.bad(): 0
我必须承认(因为我从来没有尝试使用 std::stringstream
将 char
转换为 std::string
)我不知道 std::stringstream
有那么糟糕选择.
我只是要警告大家,我的代码包含少量法语和英语,所以如果您不理解变量或其他内容,请务必询问并将其视为免费法语 class 哈哈。好吧,我有一个项目,其中包括为学校使用创建一个时间表,我负责管理 "time" 部分,即为教授创造时间间隔和空间来完成他们的 classes。为了确保所有情况都能正常工作,我需要确保 2 classes 不会在同一时间和地点发生。在我的函数 "rajoutcours" 中,法语中的意思是 "AddsClass",我接受了几个参数:
- 材料=主题
- heure_deb = 开始时间
- heure_fin = 结束时间
- date = 嗯,这是 class 的日期
- salle = 房间。
在我的函数中,我创建了 3 个变量,它们是 heure_start(另一个 class 开始的时间),heure_end(另一个 class 结束的时间),日期和房间(其他 class 事件发生的日期和它们发生的房间)。我使用字符串运算符“+”属性 填写这些变量,我将 txt 文件(其他 classes)中行的每个字符转换为 1 个字母的字符串,以便我可以添加它们使用 sstream 库。奇怪的是,只有一个字符被转换为字符串,而其他字符却没有,我真的不明白为什么。
无论如何,我对此了解很多,但我已经尝试找出问题好几天了,但我看不出问题出在哪里。谢谢大家的帮助。
void Utilisateur::rajout_cours(string matiere, string heure_deb, string heure_fin, string date, string salle )
{
ifstream user_in ("Cours.txt"); // txt file where classes are listed
ofstream user_out;
user_out.open("Cours.txt", ofstream::out | ofstream::app);
user_out; //write
string ligne; //line variable which reads the lines of the txt file
string heure_start; // time at which the class starts
string heure_end; // time at which the class ends
string day; // self explanatory
string room; // ie before
int i=0;
int j=0;
int cptr=0;
int a,b,c,d;
stringstream ss; // this is supposed to convert char into string
while (getline(user_in,ligne))
{
for(i=0;i<ligne.size();i++)
{
if(ligne.at(i)=='$' && cptr==0)
{
a=i;
cptr++;
cout << "Premier '$'" << endl; // Keep in mind that the '$' is the delimiter when i write on the txt file, it's also a way to know where I am.
for(j=0;j<a;j++)
{
char tmpc='[=10=]';
string tmps;
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
heure_start=heure_start+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==1)
{
b=i;
cptr++;
cout << "Deuxieme '$'" << endl;
for(j=a+1;j<(b);j++)
{
char tmpc = '[=10=]';
string tmps;
tmpc=ligne.at(j);
ss << tmpc;// conversion char en string
cout << "Lettre char a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;// conversion complète à priori
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
heure_end=heure_end+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==2)
{
c=i;
cptr++;
cout << "3eme '$'" << endl;
for(j=b+1;j<(c);j++)
{
char tmpc='[=10=]';
string tmps="";
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
room=room+tmps;
}
}
else if(ligne.at(i)=='$' && cptr==3)
{
d=i;
cptr++;
cout << "4eme '$'" << endl;
for(j=c+1;j<(d);j++)
{
char tmpc='[=10=]';
string tmps="";
tmpc=ligne.at(j);
ss << tmpc;
cout << "Lettre char a la case " << j << " : "<< tmpc << endl; //I want to know what's the char in the j-th character of the word
ss >>tmps;
cout << "Lettre string a la case " << j << " : "<< tmps << endl; // I want to display it's string version
day=day+tmps;
}
}
}
}
if(heure_deb==heure_start && heure_fin==heure_end && date==day && salle==room) // I make sure here that the class I'm writing isn't already written in the file and in that case we leave the program.
{
cout << "Impossible d'ajouter un cours ! Un cours de " << matiere <<"a deja lieu à ce moment! Changez d'horaires ou de salles. " << endl;
exit(1);
}
cout <<"ecris" << endl;
user_out << heure_deb << "$"<< heure_fin << "$" << salle << "$" << date << "$" << matiere << endl; // If not, write the new class.
}
我已经提到过将 char
转换为 std::string
非常简单,只需使用 resp.构造函数 std::string::string(size_t count, char ch)
:
char c = 'A';
std::string str(1, c); // constructs a string str with one character
然而,在我第三次阅读这个问题后,我意识到它实际上应该按照 OP 尝试的方式工作。
所以,对我来说,实际的问题是:
为什么std::stringstream
不能重复交替使用output/input?
过了一会儿,我想起了stringstream
中的"stream"。
嗯,它可以——考虑到在用输出填充它(例如 <<
)并用输入清空它(例如 >>
)之后,它的内部状态变为 eof
,其中下一次读取将导致 fail
状态。所以,(虽然我仍然会推荐使用我上面描述的更简单的方法),
- 要么在重新使用之前重置
std::stringstream
的状态(std::stringstream::clear()
对此有好处。) - 或者只使用
std::stringstream
的本地实例(通过将 stringstream 的构造和 input/output 语句括在一对额外的大括号{ }
中)
一个小例子:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
{ // "recycle" one instance of std::stringstream
std::stringstream sstr;
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
sstr << c;
std::string str;
sstr >> str;
std::cout << "str: '" << str << "', "
<< "sstr.good(): " << sstr.good() << ", "
<< "sstr.eof(): " << sstr.eof() << '\n';
sstr.clear();
}
}
{ // one instance per I/O
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
std::stringstream sstr;
sstr << c;
std::string str;
sstr >> str;
std::cout << "str: '" << str << "'\n";
}
}
// done
return 0;
}
输出:
c: 'A', str: 'A', sstr.good(): 0, sstr.eof(): 1
c: 'B', str: 'B', sstr.good(): 0, sstr.eof(): 1
c: 'C', str: 'C', sstr.good(): 0, sstr.eof(): 1
c: 'A', str: 'A'
c: 'B', str: 'B'
c: 'C', str: 'C'
三思后,我意识到在这种特定情况下必须清除 eof
状态还有另一个原因:
- 输出正好是一个
char
- 输入试图填充
std::string
(这在某种程度上更贪婪)并读取直到分隔符或文件结尾(并且总是后者发生)。
检查过这个:
#include <iostream>
#include <sstream>
int main()
{
// "recycle" one instance of std::stringstream
std::stringstream sstr;
for (char c = 'A'; c <= 'C'; ++c) {
std::cout << "c: '" << c << "', ";
sstr << c;
char cIO;
if (sstr >> cIO) std::cout << "cIO: '" << cIO << "'\n";
else std::cout << "reading cIO failed\n";
}
// done
return 0;
}
输出:
c: 'A', cIO: 'A'
c: 'B', cIO: 'B'
c: 'C', cIO: 'C'
现在,即使没有 sstr.clear()
它也能正常工作,因为它从不尝试读取文件末尾(又名字符串流)。
提到 "greedy" 阅读 operator>>(std::stringstream&, std::string)
让我想到了另一个想法:
如果任务中的 char
是分隔符会怎样?
#include <iostream>
#include <sstream>
#include <string>
int main()
{
char c = ' ';
std::stringstream sstr;
sstr << c;
std::cout << "c: '" << c << "', ";
std::string str;
sstr >> str;
std::cout << "str: '" << str << "'\n";
std::cout
<< "sstr.good(): " << sstr.good() << '\n'
<< "sstr.eof(): " << sstr.eof() << '\n'
<< "sstr.fail(): " << sstr.fail() << '\n'
<< "sstr.bad(): " << sstr.bad() << '\n';
// done
return 0;
}
输出:
c: ' ', str: ''
sstr.good(): 0
sstr.eof(): 1
sstr.fail(): 1
sstr.bad(): 0
我必须承认(因为我从来没有尝试使用 std::stringstream
将 char
转换为 std::string
)我不知道 std::stringstream
有那么糟糕选择.