C++ 逐行处理文件并解析该行以获得单独的变量
显然,我需要逐行处理这个文件,然后在每一行中,我需要从该行中提取两个数字,并将它们放在一个映射中,其中数字是一个节点的ID,名称是字符串,因此0将是我映射中节点a的键 我想我已经把一行一行地写下来了,但即使是这样也有点困难 以下是我所拥有的:C++ 逐行处理文件并解析该行以获得单独的变量,c++,file,parsing,line,C++,File,Parsing,Line,显然,我需要逐行处理这个文件,然后在每一行中,我需要从该行中提取两个数字,并将它们放在一个映射中,其中数字是一个节点的ID,名称是字符串,因此0将是我映射中节点a的键 我想我已经把一行一行地写下来了,但即使是这样也有点困难 以下是我所拥有的: bool read_index(map<long, string> &index_map, string file_name) { //create a file stream for the file to be read
bool read_index(map<long, string> &index_map, string file_name)
{
//create a file stream for the file to be read
ifstream index_file(file_name);
//if file doesn't open then return false
if(! index_file.is_open())
return false;
string line;
//read file
while(! index_file.eof())
{
getline(index_file,line);
stringstream ss(line);
while(ss)
{
//process line?
}
}
//file read
return true;
}
如果字符串中没有空格,则可以忽略换行符,只提取标记:
void read_index(std::istream & infile, std::map<long, std::string> & index_map)
{
long n;
std::string token;
while (infile >> n >> token) { index_map[n] = std::move(token); }
}
如您所见,基于行的处理的好处是您还可以处理无效行并跳过这些行。第一个纯粹基于令牌的代码在无法识别令牌时立即停止。您误用了eof。请尝试类似以下内容:
bool read_index(map<long, string> &index_map, string file_name)
{
//create a file stream for the file to be read
ifstream index_file(file_name);
//if file doesn't open then return false
if(!index_file)
return false;
string line;
//read file
while(getline(index_file, line))
{
stringstream ss(line);
long n;
std::string token;
if (ss >> n >> token)
{
//process line
index_map[n] = token;
}
else
{
// error do something
}
}
//file read?
return !file.fail();
}
字符串中有空格吗?我做了很多分析,我必须说我更喜欢按行输入,这样可以更容易地正确处理错误。这类代码通常需要两行。但当你处于防守状态时,在完全安全之前,你会发现自己被几十条防线所包围@v、 奥多:这个代码没有防御性。这是完全正确的。我不太明白你的评论或其中的链接的相关性。完全相关,你建议的第二个版本是防御型的,你的第一个版本是干净的两行版本。@v.oddou:正如我在回答中所说,这两个版本做了不同的事情。两者都不是防御性的。他们只是在编程。也许错误这个词有误导性,我改了。当您处理I/O时,您不能强制执行先决条件。你只需要处理你得到的任何输入。第一个是否真的有必要?不是严格需要的,没有,但它确实避免了浪费时间调用getline,如果你事先知道它们会失败,那么它就会失败。此外,它还为您提供了记录/调试失败操作的机会。
bool read_index(map<long, string> &index_map, string file_name)
{
//create a file stream for the file to be read
ifstream index_file(file_name);
//if file doesn't open then return false
if(!index_file)
return false;
string line;
//read file
while(getline(index_file, line))
{
stringstream ss(line);
long n;
std::string token;
if (ss >> n >> token)
{
//process line
index_map[n] = token;
}
else
{
// error do something
}
}
//file read?
return !file.fail();
}