push_back 时跳过向量位置

Posted

技术标签:

【中文标题】push_back 时跳过向量位置【英文标题】:skipping vector position when pushing_back 【发布时间】:2010-08-22 22:21:22 【问题描述】:

我正在将文件中的数据读取到名为data 的字符串向量中。对于这个数据向量,我通过名为output_string 的主函数推回一个新字符串。 Output_string 只是通过命令行传入的参数的组合。完成所有操作后,我写回我的文件(使用新字符串更新文件)。但是,当我这样做时,第一个命令行参数之后的所有内容,只要再次遇到data.push_back(output_string);,它就会跳过一个向量位置。

例如文件内容

bob
jack
snack

读入向量后,

数据向量内容

bob
jack
snack

添加新字符串后,新字符串“john”数据向量内容变为

bob
jack
snack
john

但是如果我再次运行程序并使用命令行再次添加一些东西,它会跳过一个向量位置

bob
jack
snack
john

peter

它对我在第一个之后添加的所有内容执行此操作。为什么要这样做?

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


 if (argc > 6)
  cout<<"[Error] too many inputs provided" << endl;
  return 0;
 

 commandProcess(argc,argv);

 outputstringformat();
 //*********
 if (cominput.rem_contpos == -1)
  readData();                        //reads data from a file into vector data
  int outlen = output_string.length();
  if (outlen > 0)
   data.push_back(output_string);  //pushing what i had in argv to vector
  

  cout<<"----------data vector------------"<<endl;
  for (int i = 0; i < data.size();i++)
   cout<<"data: " << data[i] << endl;
  

  ofstream outfile("contactlist.dat");
  number_of_contacts = data.size();
  if(outfile.is_open())
   for (int i =0; i < number_of_contacts; i++)
    outfile << data[i] << endl; //copying evertthing back to file, including the new argument passed to data
   
   outfile.close();
  
 
 return 0;

编辑: 这也是我处理参数的方式,我将它们组合成一个字符串。我有一个暗示这可能是问题,但仍然没有看到它......:|

void outputstringformat()

    if (cominput.name1.length() != 0 )
        output_string = cominput.name1;
       
    if (cominput.name2.length() != 0 )
        output_string = output_string + " " + cominput.name2;
    
    if (cominput.name3.length() != 0 )
        output_string = output_string + " " + cominput.name3;
    
    if (cominput.email.length() != 0 )
        output_string = output_string + " " + cominput.email;
    
    if (cominput.phone.length() != 0 )
        output_string = output_string + " " + cominput.phone;
    

用 reaData 更新

void readData()
    ifstream myfile("contactlist.dat");
    if(myfile.is_open())
        while(!myfile.eof())
            getline(myfile,line);
            data.push_back(line);
        
        myfile.close();
    

【问题讨论】:

【参考方案1】:

这是你的问题:

while(!myfile.eof())
    getline(myfile,line);
    data.push_back(line);

myfile.eof() 只会在您尝试读取文件末尾之外的内容之后为真;它不会告诉您下一次读取是否会到达 EOF。所以你的最后一个getline 不会读取任何内容(由于EOF),但无论如何你都会将空的line 字符串放入向量中。

这个循环的正确写法很简单:

while(getline(myfile,line)) 
    data.push_back(line);
    

之所以有效,是因为getline 的返回值是从(myfile,在本例中)读取的流,并且 iostream 被设计为在测试中使用时,例如 if (myfile),它们评估当且仅当既没有遇到错误也没有遇到 EOF 时为 true。这样写,当到达 EOF 时,getline 将返回 myfile,这将在 while 测试中评估为 false,因此该行不会被推入向量中。

此方法还有一个优点,即在出现 EOF 以外的错误时停止文件读取。

【讨论】:

【参考方案2】:

可能发生的情况是,文件内容最初是字符串:

"bob\n"
"jack\n"
"snack" // no line feed

逐行表示“bob”、“jack”和“snack”。当您将这些行与“john”endl 一起写出时,文件的内容是:

"bob\n"
"jack\n"
"snack\n"
"john\n" // line feed

您可能将其读作“bob”、“jack”、“snack”、“john”和“”,因为在读取“john\n”之后,从技术上讲,还没有到达文件末尾但是,下次尝试读取时会到达。

编辑:这个readData 可能对你有用:

void readData() 
    ifstream myfile("contactlist.dat");
    if(myfile.is_open())
        string l;
        while(myfile >> l)
            data.push_back(l);
        
        myfile.close();
    

如http://codepad.org/INgm757m 所示,无论contactlist.dat 中的最后一个字符是否为换行符,此版本都将具有相同的行为。

【讨论】:

【参考方案3】:

这里真的不够,但我怀疑readData() 正在向向量添加一个空字符串。试试这个:

// Put this right after readData()
cout<<"----------data vector from file------------"<<endl;
for (int i = 0; i < data.size();i++)
  cout<<"data[" << i << "]: " << data[i] << endl;

编辑: 我不熟悉你的getline 版本,但它看起来好像在拾取最终的 CR 或 LF 或其他。试试这个:

void readData()
    ifstream myfile("contactlist.dat");
    if(myfile.is_open())
        while(!myfile.eof())
            getline(myfile,line);
            if(myfile.gcount()>0)  // checking for zero-length string
                data.push_back(line);
            
        
        myfile.close();
    

【讨论】:

你是对的......你能告诉我这里有什么问题吗? void readData() ifstream myfile("contactlist.dat"); if(myfile.is_open()) while(!myfile.eof()) getline(myfile,line); data.push_back(line); myfile.close();

以上是关于push_back 时跳过向量位置的主要内容,如果未能解决你的问题,请参考以下文章

使用 GridSearchCV 时跳过禁止的参数组合

向量的向量占用的内存

如何在 STL 向量中实现 push_back?

在展开期间将向量成员推入向量:vector.push_back(vector[0])

c ++ push_back第一个向量和按升序排序向量[关闭]

使用 push_back 向向量添加非空字符串,向量内容为空。为啥字符串没有添加到向量中?