С++ Чтение файла с использованием цикла while, начало со строки 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++;
}

Заранее спасибо!


person Michael    schedule 08.07.2012    source источник
comment
Проверьте stackoverflow.com/questions/5431941/ пока вы этим занимаетесь.   -  person Mat    schedule 08.07.2012
comment
Вам также придется сохранить x в какой-нибудь файл. И если вы собираетесь использовать C++, пожалуйста, откажитесь от массивов символов, memset, strcpy и тому подобного. Вместо этого используйте std::string и стандартные алгоритмы.   -  person jrok    schedule 08.07.2012


Ответы (4)


Если вы действительно хотите использовать imgresults.txt в качестве информации о том, где вы должны начать из входного файла, то лучшее, что вы можете сделать, это иметь цикл while для чтения x строк из входного файла непосредственно перед циклом, в котором вы читаете входной файл.

while (x--) {
    fgets(sLine, MAX_FILENAME_SIZE, fIn);
}

Лучшим решением, вероятно, было бы записать состояние обработки в другой файл, чтобы вам не приходилось читать входной файл построчно, а можно было сразу искать известное смещение в файле.

person Jari    schedule 08.07.2012

Используйте ifstream::tellg для извлечения и сохранения текущей позиции файла, когда программа была закрыта.

Используйте ifstream::seekg, чтобы восстановить это положение при перезапуске программы.

person Sebastian Hoffmann    schedule 08.07.2012

Прежде чем читать каждую строку, сохраните текущие смещения во входном и выходном файле в отдельный файл, возвращаясь к началу и каждый раз перезаписывая существующие данные.

Когда / если вы перезапустите, прочитайте смещения из этого файла, найдите эти точки и начните работать оттуда.

person Jerry Coffin    schedule 08.07.2012

Вы можете просто читать строки параллельно из обоих файлов и останавливаться, когда дойдете до конца файла результатов. Когда цикл заканчивается, вы уже отбрасываете имена файлов, которые уже были обработаны.

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
}

Не самое эффективное решение, но избавляет вас от необходимости сохранять смещения. Только убедитесь, что перед самой первой обработкой файл результатов полностью пуст (или вообще не существует), иначе этот код пропустит первую строку файла имен.

person jrok    schedule 08.07.2012
comment
К сожалению, мне нужно заполнить файл результатов. Когда я перезапускаю программу, она должна иметь возможность продолжить чтение с того места, на котором она остановилась, и она должна продолжить добавление в файл результатов. После каждой записи стоит '\n', так что это не сработает :( В любом случае спасибо! - person Michael; 08.07.2012
comment
@Michael Обновил вопрос. Конечно, вы сможете заполнить файл. - person jrok; 08.07.2012