istream& operator>>(istream& s, vector<Order>& ord) {
string c{};
bool got_customer = false;
Customer temp_customer{};
vector<Purchase>vec_purchase{};
while (s >> c) {
cout << "Erstes Wort der Zeile: "<<c << endl;
if (!got_customer) { //c[0] == '#'
c.erase(c.begin()); //löscht erstes Element vom string
int k_nummer{};
string k_vname{};
string k_nname{};
string k_plz{};
string k_stadt{};
k_nummer = stoi(c); //string to int
s >> k_vname >> k_nname >> k_plz>>k_stadt;
k_vname += " " + k_nname;
temp_customer = Customer(k_nummer, k_vname, k_plz, k_stadt);
got_customer = true;
} else {
string p_name{};
double p_preis{};
int p_menge{};
p_name = c;
s >> p_preis>>p_menge;
cout << p_name << " " << p_preis << " " << p_menge << endl;
vec_purchase.push_back(Purchase{p_name, p_preis, p_menge});
}
cout<<s.peek()<<endl;
if (s.peek() == '#') {
ord.push_back(Order{temp_customer, vec_purchase});
temp_customer = Customer{};
vec_purchase.clear();
got_customer = false;
}
}
}
这是txt文件:
#725454 Schenker Rudolf DE-30159 Hannover
Shirt 135.95 1
Tie 89.59 1
#987654 Orbison Roy US-TN37075 Hendersonville
Mug 1.49 3
T-Shirt 14.90 1
#123456 Petty Tom US-FL32641 Gainesville
Flashlight 12.95 2
#246802 Hite Bob US-CA90291 Venice
CannedBeans 0.89 10
CannedTomatoes 1.79 6
#246802 Hite Bob US-CA90291 Venice
CanOpener 0.48 1
Spoon 1.49 4
Needle 0.05 100
以'#'开头的行是Customer对象。 其他行是购买对象。
我正在试图查看即将到来的char,但我一次又一次地获得相同的字符。在这种情况下,我总是得到'13'作为s.peek()的输出。
€二叔: 谢谢@Mark Ransom。 如果有人遇到同样的问题,这是工作代码。 :)
istream& operator>>(istream& s, vector<Order>& ord) {
string c{};
bool got_customer = false;
Customer temp_customer{};
vector<Purchase>vec_purchase{};
while (s >> c) {
if (!got_customer) {
c.erase(c.begin()); //deletes first char of string
int k_nummer{};
string k_vname{};
string k_nname{};
string k_plz{};
string k_stadt{};
k_nummer = stoi(c); //string to int
s >> k_vname >> k_nname >> k_plz>>k_stadt>>ws;
k_vname += " " + k_nname;
temp_customer = Customer(k_nummer, k_vname, k_plz, k_stadt);
got_customer = true;
} else {
string p_name{};
double p_preis{};
int p_menge{};
p_name = c;
s >> p_preis>>p_menge>>ws;
vec_purchase.push_back(Purchase{p_name, p_preis, p_menge});
}
if (s.peek() == 35||s.peek() == -1 ) { //35 (in ascii) -> # , -1 -> end of txt file
ord.push_back(Order{temp_customer, vec_purchase});
temp_customer = Customer{};
vec_purchase.clear();
got_customer = false;
}
}
}
答案 0 :(得分:1)
当您从流中读取时,输入将停止在第一个空白字符上。十进制代码为13的字符是ASCII CR,它出现在Windows的每一行的末尾;它被认为是空白。您需要跳过空格才能找到下一个重要字符。您可以使用std::ws
执行此操作。
s >> k_vname >> k_nname >> k_plz >> k_stadt >> std::ws;
s >> p_preis >> p_menge >> std::ws;
答案 1 :(得分:0)
s >> p_preis>>p_menge;
这是为了读取带有记录的行上的最后两个字段。紧接着:
if (s.peek() == '#') {
你明显的目的是窥探下一行的第一个字符,检查下一行是否以#
开头。
嗯,这不会发生,就像那样......
问题是>>
运算符在处理完输入后不会消耗行尾字符。 peek()
这里将为您提供换行符。惊喜。
给出一个示例输入行:
Tie 89.59 1
&#34; 1&#34;部分将由>>p_menge
阅读,并存储到menge
。 1
之后的下一个字符将是换行符,而peek()
将很乐意为您提供这些字符。
这是完成此任务的错误方法。只有一种正确的方法来读取包含文本行的文件:
std::getline()
那就是它。 std::getline()
,没有别的。了解如何使用它。我会让你的生活更加简单。
您当然可以使用>>
运算符一次读取输入文件中的行,零碎,一个字段,但正如您所发现的那样,这是一个容易出错且容易出错的过程。太多雷区和陷阱。
当然,使用>>
运算符可以做到这一点,但是如何做到这一点并不总是显而易见的,需要完全理解所有细微差别格式化的输入操作。
遗憾的是,有太多介绍性的C ++书籍开始时会出现使用>>
运算符读取由文本行组成的输入的示例。这只会使大多数初学者感到困惑,并导致问题和误解,例如这些。
您需要重写程序以使用std::getline()
一次读取一行文本。故事结束。
一旦你将整行文字读成std::string
,并检查它是否以#
字符开头:如果你觉得它 然后 您可以将整行填入std::istringstream
,然后在受控环境中使用>>
运算符。