Не могу преобразовать char в строку с помощью stringstream C++
Я просто хочу предупредить вас, что мой код содержит небольшие фрагменты французского и английского языков, поэтому, если вы не понимаете переменную или что-то еще, пожалуйста, спросите и посчитайте это бесплатным классом французского, ха-ха. Итак, у меня есть проект, который состоит из создания расписания для школ, и я отвечаю за управление частью "времени", то есть создание временных промежутков и помещений для преподавателей для их занятий. Чтобы убедиться, что все ситуации работают правильно, мне нужно убедиться, что 2 класса не могут происходить одновременно и в одном месте. В моей функции "rajoutcours", что на французском означает "AddsClass", я беру несколько параметров:
- matiere = тема
- heure_deb = время начала
- heure_fin = время окончания
- дата = хорошо, это дата урока
- Салле = комната.
В моей функции я создаю 3 переменные: heure_start (время начала другого класса), heure_end (время окончания другого класса), день и комната (день, когда происходят другие классы, и комната, в которой они находятся). Я заполняю эти переменные, используя свойство строкового оператора "+", где я преобразую каждый символ строки в моих текстовых файлах (которые являются другими классами) в строки с 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='\0';
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 = '\0';
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='\0';
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='\0';
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.
}
1 ответ
Я уже упоминал, что это очень просто конвертировать char
к std::string
просто используя соотв. конструктор std::string::string(size_t count, char ch)
:
char c = 'A';
std::string str(1, c); // constructs a string str with one character
Однако после того, как я прочитал вопрос в третий раз, я понял, что на самом деле он должен работать так, как ОП пытался это сделать.
Итак, для меня актуальный вопрос привел:
Зачем std::stringstream
не может использоваться повторно для чередующегося вывода / ввода?
Через некоторое время я вспомнил "поток" в stringstream
,
Ну, может - учитывая тот факт, что после заполнения его выводом (например, <<
) и очистить его с помощью ввода (например, >>
) это внутреннее состояние становится eof
где следующее чтение приведет к fail
государство. Итак, (хотя я все же рекомендовал бы использовать мой описанный выше более простой метод),
- либо сбросить состояние
std::stringstream
перед повторным использованием (std::stringstream::clear()
хорошо для этого.) - или просто использовать локальные экземпляры
std::stringstream
(заключив конструкцию stringstream и операторы ввода / вывода в дополнительную пару фигурных скобок{ }
)
Небольшой пример:
#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()
так как он никогда не пытается прочитать за конец файла (он же stringstream).
Упоминание "жадного" чтения 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
Я должен признать, что (как я никогда не пытался преобразовать char
в std::string
используя std::stringstream
) Я не знал, что std::stringstream
это плохой выбор.