提问人:Michael 提问时间:7/8/2012 更新时间:7/9/2012 访问量:2557
C++ 使用 while 循环读取文件,从行“x”开始
C++ Reading file using while loop, start at line "x"
问:
我已经在这个问题上卡了一段时间了。我这里有一个循环,它将读取包含文件名的文本文件。循环逐个读取这些行,并通过变量 sFileName 将其设置到内存中。稍后会调用 sFileName 来加载图像,程序会在循环加载图像时逐个执行此操作。然后,用户为图像选择一个标签并加载下一个标签。标记和图像文件名将导出到另一个名为 imgresults.txt 的文本文件中。现在,带有文件名的文本文件只有几千行。因此,如果用户必须退出程序并尝试稍后继续,则循环将重新启动,而不是在程序关闭时停止。
我正试图找到一种方法让循环从那时开始。到目前为止,我决定使用 getline() 来计算 imgresults.txt 中当前有多少行,因为这将给出已经通过程序运行的图像数量。这个数字存储在变量“x”中。我一直在做很多研究,但我就是找不到如何为 while 循环设置条件以从行“x”开始。你们有什么建议吗?另外,如果您需要任何澄清,请询问。我只包含了有关循环的代码,因为加载图像的代码等是完美的。
int _tmain(int argc, _TCHAR* argv[])
{
int value = 0;
int nCounter = 0;
FILE* fIn = NULL;
char * sLine = new char[MAX_FILENAME_SIZE];
char * sFileName = new char [MAX_FILENAME_SIZE];
char * s = new char [MAX_FILENAME_SIZE];
#define ImgListFileName "path"
#define ImgRepository "path"
if ((fIn = fopen(ImgListFileName,"rt"))==NULL)
{
printf("Failed to open file: %s\n",ImgListFileName);
return nCounter;
}
ifstream imgresults;
imgresults.open ("imgresults.txt");
int x=0;
string line;
while(!imgresults.eof()) {
getline (imgresults, line);
x++;
}
srand (time(NULL));
cout << x;
while(!feof(fIn)){
memset(sLine,0,MAX_FILENAME_SIZE*sizeof(char));
memset(sFileName,0,MAX_FILENAME_SIZE*sizeof(char));
memset(s,0,MAX_FILENAME_SIZE*sizeof(char));
fgets(sLine,MAX_FILENAME_SIZE,fIn);
strncpy(s,sLine,65);
strcat(sLine,"\0");
strcat(sFileName,s);
printf (sFileName);
nCounter++;
}
提前致谢!
答:
使用 ifstream::tellg 检索和存储程序关闭时文件的当前位置。
使用 ifstream::seekg 在 porgramm 重新启动时恢复该位置。
如果你真的想使用 imgresults.txt 作为你应该从输入文件开始的信息,那么你能做的最好的事情就是在你读取输入文件的 while 循环之前有一个 while 循环从输入文件中读取 x 行。
while (x--) {
fgets(sLine, MAX_FILENAME_SIZE, fIn);
}
更好的解决方案可能是将处理状态写入另一个文件,这样您就不必逐行读取输入文件,但您可以立即查找文件中的已知偏移量。
在读取每一行之前,请将输入和输出文件中的当前偏移量保存到一个单独的文件中,每次都返回开头并覆盖现有数据。
当您重新启动时,请从该文件中读取偏移量,寻找这些点,然后从那里开始工作。
您可以从两个文件中并行读取行,并在到达结果文件末尾时停止。循环结束时,您已经丢弃了已处理的文件名。
ifstream results("results.txt");
ifstream names("names.txt");
if (results && names) {
std::string temp1, temp2;
while (getline(results, temp1) && getline(names, temp2)) ; /* do nothing */
}
if (names) {
// process the rest
}
这不是最有效的解决方案,但它为您省去了节省偏移量的麻烦。只需确保在第一次处理之前,结果文件是完全空的(或根本不存在),否则此代码将跳过名称文件的第一行。
评论
x
std::string