【问题标题】:Can't convert char to string with stringstream C++ [closed]无法使用 stringstream C++ 将 char 转换为字符串 [关闭]
【发布时间】:2023-04-05 06:58:01
【问题描述】:

我只是要警告大家,我的代码在这里和那里都包含少量法语和英语,所以如果您不理解变量或其他内容,请询问并将其视为免费的法语课程哈哈。好的,所以我有一个项目,其中包括创建一个供学校使用的时间表,我负责管理“时间”部分,即为教授上课创建时间间隔和房间。为了确保所有情况都能正常工作,我需要确保两个课程不能同时在同一时间和地点发生。在我的函数“rajoutcours”(法语中的意思是“AddsClass”)中,我接受了几个参数:

  • matiere = 主题
  • heure_deb = 开始时间
  • heure_fin = 结束时间
  • date = 好吧,这是上课的日期
  • sale = 房间。

在我的函数中,我创建了 3 个变量,它们是 heure_start(另一个课程开始的时间)、heure_end(另一个课程结束的时间)、day 和 room(其他课程发生的日期以及它们发生的房间) )。我使用字符串运算符“+”属性填充这些变量,在该属性中,我将 txt 文件(其他类)中的行的每个字符转换为 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. 



}

【问题讨论】:

标签: c++ string char sstream


【解决方案1】:

我已经提到将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不能重复用于交替输出/输入?

过了一会儿,我想起了stringstream中的“流”。

好吧,它可以——考虑到在用输出填充它(例如&lt;&lt;)并用输入清空它(例如&gt;&gt;)之后,它的内部状态变为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'

Live Demo on coliru


三思之后,我意识到在这种特定情况下需要清除 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'

Live Demo on coliru

现在,即使没有sstr.clear(),它也可以工作,因为它从不尝试读取文件末尾(又名字符串流)。

提到operator&gt;&gt;(std::stringstream&amp;, 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

Live Demo on coliru

我必须承认(因为我从未尝试使用 std::stringstreamchar 转换为 std::string)我不知道 std::stringstream 是一个糟糕的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    相关资源
    最近更新 更多