James kingswell Ответов: 1

попытка seekp строка за строкой и замена строки в файле


Итак, моя проблема заключается в том, что я не могу понять, как "установить tellp ()" в начало определенной строки, а затем заменить ее новой. Я также только что понял, что мне также придется выяснить, как избежать написания любой из следующих строк.. Я, наверное, должен быть в состоянии понять, что, хотя из. Это то, что я пробовал до сих пор

std::fstream indiLine;
indiLine.open ("indiTest.mdl",std::ios::in | std::ios::out); //| std::ios::app);
if (indiLine.is_open())
{
   std::string inOut;
   int line_num = 0;
   //find line
   while (getline(indiLine,inOut))
   {
         if (line_num-1 == vNum) //stop at a particular line of text denoted by vNum
         {  std::cout << inOut << std::endl ;
            break; }
         line_num++;
   }
   indiLine.seekp(indiLine.tellg());
   indiLine << "R";
   indiLine.close();
}
else{ debugOut("Save Failure On Open",500); }


и выход для конкретных линий, которые я тестировал:

Цитата:
перед процедурой;
X200Y200Z200E8D5
X-200Y200Z200E1D5
после подпрограммы;
X200Y200Z20RE8D5
X-200Y200ZR00E1D5

и это 8-я и 9-я строки, когда "vNum" находится в 5, а затем в 6, так что они должны быть 6-й и 7-й строками. Или, скорее, это те, за которыми я охочусь в этих конкретных случаях.
так что tellg() дает мне неправильную позицию.. Если бы это было в конце линии, я мог бы просто сделать что-то вроде
indiLine.seekp(indiLine.tellg-inOut.length());

но это не значит, что я действительно не знаю, что делать. Кроме того, мне кажется вероятным, что я не смогу просто вычесть " int "из типа, который возвращает" tellg ()".
Любые намеки на то, что нужно сделать, чтобы решить эту проблему таким образом, были бы действительно великолепны, и если я подхожу к этому с совершенно неправильной точки зрения, дайте мне знать, что вы имеете в виду, еще лучше. Спасибо, ребята, вы все потрясающие. :)

Jochen Arndt

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

После вызова getline () позиция, возвращаемая tellg (), указывает на следующую строку. Чтобы получить позицию для начала строки, просто сохраните предыдущую позицию в переменной и используйте ее для поиска (установите переменную в 0 при запуске и используйте tellg() в качестве последней команды внутри цикла).

1 Ответов

Рейтинг:
1

Aescleal

Самый прямой и относительно безопасный способ линейного редактирования файла-это:

Откройте исходный файл
Откройте файл назначения
Читайте каждую строку по очереди из исходного файла:
- если это не правильная строка, то запишите ее в файл назначения
- если это та строка, которую вы хотите, отбросьте ее и скопируйте новую строку в файл назначения

Удалите исходный файл
Переименовать файл назначения

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


James kingswell

Спасибо :) звучит идеально. Как мне переименовать файл назначения? есть ли у fstream такая возможность? что бы я использовал? На самом деле я не очень часто пользовался хранилищем файлов.. :/

Aescleal

Потоки не знают о файлах, поэтому я бы выбрал std::remove и std::rename, если только у вас нет доступа к файловой системе boost::.