旧的(类C)fscanf方法的现代等价(C ++)样式是什么?

如果我想在使用分号分隔符读取文件时将旧C代码“升级”为更新的C ++,那么最佳选择是什么:

/* reading in from file C-like: */ fscanf(tFile, "%d", &mypost.nr); /*delimiter ; */ fscanf(tFile, " ;%[^;];", mypost.aftername);/* delimiter ; */ fscanf(tFile, " %[^;]", mypost.forename); /*delimiter ; */ fscanf(tFile, " ;%[^;];", mypost.dept);/*delimiter ; */ fscanf(tFile, " %[^;];", mypost.position);/* delimiter ; */ fscanf(tFile, "%d", &mypost.nr2); //eqivalent best C++ method achieving the same thing? 

你可以为你的struct重载istream上的右移运算符,所以:

 std::istream& operator>>(std::istream& is, mypost_struct& mps) { is >> mps.nr; is.ignore(1, ';'); is.getline(mps.forename, 255, ';'); is.getline(mps.aftername, 255, ';'); is >> mps.dept; is.ignore(1, ';'); is >> mps.position; is.ignore(1, ';'); is >> mps.nr2; return is; } 

随后,输入就像is >> mypost;一样简单is >> mypost; ,你在哪里打开的文件。

编辑:@UncleBens感谢您指出这一点,我忘了考虑空间。 我已经更新了答案,假设forename和aftername可能包含空格。 关于分隔符的双重引用,这有点令人尴尬……

我只是使用结构定义检查它,如下所示:

 struct mypost_struct { int nr; char forename[255], aftername[255]; int dept, position, nr2; }; 

..结果如预期。

正如@susmits所说,但你也可以使用返回的流作为条件,如:

 if (is >> mps.nr && is.ignore(1, ";") && is >> mps.aftername && ...) { // all is well ... } else { // bad input format } 

甚至:

 if (is >> mps.nr >> ignore(";") >> mps.aftername >> ...) { // all is well ... } else { // bad input format } 

如果我想将旧的C代码“升级”为更新的C ++,那么最佳选择是什么?

恕我直言,最好的方法是逐行读取文件并使用正则表达式进行解析 。