【问题标题】:C++ Vector iteration failing for single element input单元素输入的 C++ 向量迭代失败
【发布时间】:2016-01-20 14:11:36
【问题描述】:

我正在尝试从用户那里获取包含 part1/1 part2/4 等条目的 txt 文件,并将其存储在向量“part_name”和“rev_id”中。所以“part_name”包含 part1 part2 ... 而“rev_id”包含 1 4 ..... 该程序在命令提示符下作为 program.exe list.txt 运行。

当 txt 文件有 2 个或更多输入时,程序运行良好,但当它有单个输入时,vector 大小显示为 2(但必须为 1)。

如果list.txt 包含part1/1 part2/4 => part_name.size() 是2

如果 list.txt 包含 part1/1 => part_name.size() 仍然是 2。

有人可以帮我解决这个问题吗?

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

int main(int argc, char*argv[])
{

std::string s ;
std::string delimiter = "/";
size_t pos;
std::vector<std::string> part_name;
std::vector<std::string> rev_id;
std::string token1,token2;


ifstream readFile (argv[1]);
if (readFile.is_open()) 
{
 while (!readFile.eof()) 
{
    readFile >> s;
    pos=s.find(delimiter);
    if((pos!=std::string::npos)&&(pos!=0))
    {

    token1 = s.substr(0, s.find(delimiter));
    token2 = s.substr(pos + delimiter.length());

    part_name.push_back(token1);
    rev_id.push_back(token2);
    }
 }
}
else{

   std::cout<<"Cannot open file"<<endl;
}
readFile.close();

  for (unsigned j=0; j < part_name.size(); j++)
 {
    cout<<part_name.size()<<endl;
    cout<<"part name j is " <<part_name[j]<<endl;
    cout<<"part id j is " <<rev_id[j]<<endl;
 }


}

【问题讨论】:

  • part1/1 是单独一行还是每行可以有多个“部分”?

标签: c++ parsing text vector


【解决方案1】:

我觉得问题出在这里

while (!readFile.eof()) 
{
readFile >> s;
pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{

token1 = s.substr(0, s.find(delimiter));
token2 = s.substr(pos + delimiter.length());

part_name.push_back(token1);
rev_id.push_back(token2);
}

上面改为

 while (readFile >> s) 
{

pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{

token1 = s.substr(0, s.find(delimiter));
token2 = s.substr(pos + delimiter.length());

part_name.push_back(token1);
rev_id.push_back(token2);
}

【讨论】:

  • 谢谢阿杰,谢谢乔治
【解决方案2】:

您最后一次阅读可能没有阅读任何内容。试试:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

int main(int argc, char*argv[])
{
    std::string s ;
    std::string delimiter = "/";
    size_t pos;
    std::vector<std::string> part_name;
    std::vector<std::string> rev_id;
    std::string token1,token2;

    ifstream readFile (argv[1]);
    if (readFile.is_open()) 
    {
        while( ( readFile >> s ).good() )
        {
            std::cerr << "Field '" << s << "'  and " << readFile.good() << std::endl;
            pos=s.find(delimiter);
            if((pos!=std::string::npos)&&(pos!=0))
            {
                token1 = s.substr(0, pos);
                token2 = s.substr(pos + delimiter.length());
                part_name.push_back(token1);
                rev_id.push_back(token2);
            }
        }
    }
    else {
        std::cout<<"Cannot open file"<<endl;
    }
    readFile.close();

    for (unsigned j=0; j < part_name.size(); j++)
    {
        cout<<part_name.size()<<endl;
        cout<<"part name j is " <<part_name[j]<<endl;
        cout<<"part id j is " <<rev_id[j]<<endl;
    }
}

【讨论】:

    【解决方案3】:

    eof() 不是在文件位置位于末尾时返回 true,而是在您尝试读取文件末尾时返回 true。因此,第一次在循环中您将输入消耗到 eof(不包括在内)。现在eof() 是假的。出于这个原因,再次进入循环,这一次提取器 (>>) 到达文件末尾。读取操作失败并且字符串没有改变(这就是为什么你会看到两次相同的值)。

    一种更好的(也更符合现代 C++ 习惯的)编码方式是使用流迭代器

    #include <iterator>
    
    // [...]
    
    std::istream_iterator<std::string> scan( readFile );
    std::istream_iteartor<std::string> eof;
    while( scan != eof )
    {
        s = *scan++;
        // s is your string
    }
    

    另外,最好让第二部分中的循环从 0 向上运行,因为向量中的元素从 0 开始编号。

    【讨论】:

      【解决方案4】:

      有些台词让我怀疑.. 为什么要从索引 1 开始迭代循环?

        for (unsigned j=1; j < part_name.size(); j++)
       {
          cout<<part_name.size()<<endl;
          cout<<"part name j is " <<part_name[j]<<endl;
          cout<<"part id j is " <<rev_id[j]<<endl;
       }
      

      你总是跳过你的向量的第一个元素。

      【讨论】:

      • 嗨亚历克西斯,这是一个错字,我确实纠正了它(j=0),但问题仍然存在......
      猜你喜欢
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多