我有以下代码从txt文件中读取输入,如下所示
Paris,Juli,5,3,6
Paris,John,24,2
Canberra,John,4,3
London,Mary,29,4,1,2
我的代码是将数据加载到地图中然后我想要打印地图内容以确保它已被正确插入,我检查在分割线时使用的m的vaue。但是,在执行期间,我将其视为继续0,这意味着它永远不会进入while循环。我以前使用过这部分代码而且有效。我无法找到我犯错的地方。
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include<map>
using namespace std;
struct info {
string Name;
int places;// i will use the binary value to identfy the visited places example 29 is 100101
// this means he visited three places (London,LA,Rome)
vector<int> times; // will represent the visiting time,e.g. 1,2,5 means london 1 time, LA
// twice and Rome five times
};
map<string,vector<info> > log;
map<string,vector<info> >::iterator i;
fstream out;
int main() {
out.open("log.txt", std::ios::in | std::ios::out | std::ios::app);
string line;
char* pt;
string temp[19];
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
pt=strtok(&line[0],"," );//split the line
int m=0;
while (pt != NULL)
{
temp[m++] = pt; // save the line info to the array
cout<<m<<" ";
pt = strtok (NULL, ",");
}
cout<<m<<" "; // during the execution I get this as continues 0s which means it is never enter the while loop
info tmp;
// read the other data
tmp.Name=temp[1];
tmp.places=atoi(temp[2].c_str());
for ( int i=3;i<=m;i++)
{
tmp.times.push_back(atoi(temp[i].c_str()));
}
// create a new object
log[temp[0]].push_back(tmp);
}
vector<int>::iterator j;
for(i=log.begin();i!=log.end();i++) {
cout<< "From "<< i->first<<" city people who travels: "<<endl;
for (size_t tt = 0; tt < (i->second).size(); tt++) {
cout<< (i->second[tt]).Name<< " went to distnations "<< (i->second)[tt].places<<" \nwith the folloing number of visiting time ";
for (j=((i->second[tt]).times).begin();j!= ((i->second[tt]).times).end();j++)
cout<<*j<<" ";
}
}
system("PAUSE");
return 0;
}
答案 0 :(得分:3)
这是一个错误
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
应该是
// for each line in the file
while (getline(out,line))
{
我发现这个错误重复的频率令人难以置信。 eof
不符合您的想法。它测试 last 读取是否因文件结束而失败。您正在使用它来尝试预测下一次读取是否会失败。它根本不起作用。
此行是错误
pt=strtok(&line[0],"," );//split the line
strtok
适用于C字符串,但无法保证它可以在std::string
上使用。
但这些都不是你真正的错误。我建议仅使用ios::in
打开文件。毕竟你只想读它。
答案 1 :(得分:1)
您无法使用std::string
对strtok
进行标记。请改用getline
:
std::string str("some,comma,separated,data");
std::string token;
while (getline(str, token, ',')) {
cout << "Token: " << token << end;
}
在每次迭代中,token
包含来自str
的下一个解析后的令牌。
答案 2 :(得分:1)
您的fstream不应在应用模式下打开。这将寻找文件到文件的末尾。从中删除std::ios::app
。
答案 3 :(得分:0)
这是错误的temp[m++] = pt; // save the line info to the array
切换到类似的东西,而不是“临时”
std::vector<std::string> vTemp;
pt=strtok(&line[0],"," );//split the line
while (pt != NULL)
{
vTemp.push_back(pt); // save the line info to the array
pt = strtok (NULL, ",");
}
同时考虑使用类似的东西进行拆分。
std::vector<std::string> SplitString(const std::string &strInput, char cDelimiter)
{
std::vector<std::string> vRetValue;
std::stringstream ss(strInput);
string strItem;
while(std::getline(ss, strItem, cDelimiter))
{
// Skip Empty
if(strItem.size()==0)
continue;
vRetValue.push_back(strItem);
}
return vRetValue;
}
答案 4 :(得分:0)
@halfelf对我的简单错误非常好的解决方案,它可以工作,但问题是现在当我打印数据时我得到了这个
From Paris city people who travels:
Juli went to distnations 5
with the folloing number of visiting time 3 6 0
John went to distnations 24
with the folloing number of visiting time 2 6
From Canberra city people who travels:
Johnwent to distnations 4
with the folloing number of visiting time 3 6
From London city people who travels:
Mary went to distnations 29
with the folloing number of visiting time 4 1 2 0
这是不正确的,因为堪萨拉和巴黎的John被添加到了6,而Juli和Mary被添加了0。 任何我错在哪里的想法,它关于时间向量,似乎我需要重置每行的值或在插入后清除内容。额外的0怎么样?