C++ 向后推_时跳过向量位置

C++ 向后推_时跳过向量位置,c++,vector,string,C++,Vector,String,我正在将文件中的数据读入一个名为data的字符串向量。对于这个数据向量,我通过名为output\u string的main函数推回一个新字符串。输出字符串只是通过命令行传入的参数的组合。完成所有这些操作后,我将写回文件(使用新字符串更新文件)。但是,当我这样做时,在第一个命令行参数之后,每当遇到数据时,它就会跳过一个向量位置再次 eg文件内容 读入向量后 数据向量内容 添加新字符串后,新字符串即“john”数据向量内容变为 但如果我再次运行程序,并使用命令行再次添加内容,它将跳过一个向量位置 b

我正在将文件中的数据读入一个名为
data
的字符串向量。对于这个数据向量,我通过名为
output\u string
的main函数推回一个新字符串。输出字符串只是通过命令行传入的参数的组合。完成所有这些操作后,我将写回文件(使用新字符串更新文件)。但是,当我这样做时,在第一个命令行参数之后,每当遇到
数据时,它就会跳过一个向量位置再次

eg文件内容

读入向量后

数据向量内容

添加新字符串后,新字符串即“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;
}
使用reaData更新

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

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

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

"bob\n"
"jack\n"
"snack" // no line feed
一行接一行是“鲍勃”、“杰克”和“零食”。当您将这些行与“john”
endl
一起写出时,文件的内容如下:

"bob\n"
"jack\n"
"snack\n"
"john\n" // line feed
您可能将其读为“bob”、“jack”、“snack”、“john”和“”,因为在读取“john”之后,技术上还没有到达文件结尾,但下次尝试读取时将到达该结尾

编辑:
readData
可能适用于您:

void readData() {
    ifstream myfile("contactlist.dat");
    if(myfile.is_open()){
        string l;
        while(myfile >> l){
            data.push_back(l);
        }
        myfile.close();
    }
}
如中所示,无论
联系人列表.dat
中的最后一个字符是否为换行符,此版本都将具有相同的行为。

这是您的问题:

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以外的错误时停止文件读取。

您说得对。。。你能告诉我这里怎么了吗?void readData(){ifstream myfile(“contactlist.dat”);if(myfile.is_open()){while(!myfile.eof()){getline(myfile,line);data.push_back(line);}myfile.close();}
"bob\n"
"jack\n"
"snack\n"
"john\n" // line feed
void readData() {
    ifstream myfile("contactlist.dat");
    if(myfile.is_open()){
        string l;
        while(myfile >> l){
            data.push_back(l);
        }
        myfile.close();
    }
}
while(!myfile.eof()){
    getline(myfile,line);
    data.push_back(line);
}
while(getline(myfile,line)) {
    data.push_back(line);
}