push_back时跳过矢量位置

时间:2010-08-22 22:21:23

标签: c++ vector string

我正在将文件中的数据读入名为data的字符串向量中。对于这个数据向量,我通过名为output_string的main推送一个新字符串。 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();
    }
}

3 个答案:

答案 0 :(得分:2)

这是你的问题:

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的设计使得在测试中使用时,例如{{ 1}},当且仅当遇到错误和EOF时,它们才会评估为真。以这种方式写,当达到EOF时,if (myfile)将返回getline,这将在while测试中评估为false,因此该行不会被推入向量中。

此方法还具有停止读取EOF以外的错误的文件的优势。

答案 1 :(得分:1)

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

"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中的最后一个字符是换行符,此版本都会有相同的行为。

答案 2 :(得分:0)

这里还没有足够的内容,但我怀疑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();
    }
}