Удалить последнюю строку в файле c
Hi All! меня такая трабла возникла, нужно удалить строку из файла (вернее найти её, и если такая строка в файле имеется удалить). Вобщем я тут функцию накатал небольшую, но почему-то она не работает. Не могу понять в чем ошибка
Вобщем логика такая: открываем файл file.txt для чтения, и считываем его построчно, пока есть что считывать. Одновременно (после прочтения каждой строки) сравниваем pattern (это только что прочитанная строка) с параметром st (эту строку и нужно удалить) если строки не эквивалентны, то заносим pattern в storyData. После того как весь файл считан, мы его очищаем (fopen ("file.txt", "w")) и записываем туда storyData, т.е. должны получить исходный файл, но без строки st, если такая там конечно имелась. ИМХО с логикой алгоритма всё в порядке, но на деле почему-то получается, что файл очищается полностью в любом случае. Помогите разобраться с этой проблемой. Что я делаю не так?
Здравствуйте, UNI_X, Вы писали:
UNI>Hi All! меня такая трабла возникла, нужно удалить строку из файла (вернее найти её, и если такая строка в файле имеется удалить). Вобщем я тут функцию накатал небольшую, но почему-то она не работает. Не могу понять в чем ошибка
UNI>
UNI>Вобщем логика такая: открываем файл file.txt для чтения, и считываем его построчно, пока есть что считывать. Одновременно (после прочтения каждой строки) сравниваем pattern (это только что прочитанная строка) с параметром st (эту строку и нужно удалить) если строки не эквивалентны, то заносим pattern в storyData. После того как весь файл считан, мы его очищаем (fopen ("file.txt", "w")) и записываем туда storyData, т.е. должны получить исходный файл, но без строки st, если такая там конечно имелась. ИМХО с логикой алгоритма всё в порядке, но на деле почему-то получается, что файл очищается полностью в любом случае. Помогите разобраться с этой проблемой. Что я делаю не так?
Здравствуйте, UNI_X, Вы писали:
UNI>Hi All! меня такая трабла возникла, нужно удалить строку из файла (вернее найти её, и если такая строка в файле имеется удалить). Вобщем я тут функцию накатал небольшую, но почему-то она не работает. Не могу понять в чем ошибка
UNI>
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, UNI_X, Вы писали:
UNI>>Hi All! меня такая трабла возникла, нужно удалить строку из файла (вернее найти её, и если такая строка в файле имеется удалить). Вобщем я тут функцию накатал небольшую, но почему-то она не работает. Не могу понять в чем ошибка
UNI>>
Исправил, только эффект тот же. Работает неправильно, файл просто очищается и всё.
Вот так теперь фыглядит эта функция.
Абсолютно ничего не изменилось.
Здравствуйте, UNI_X, Вы писали:
UNI>Исправил, только эффект тот же. Работает неправильно, файл просто очищается и всё.
UNI>Вот так теперь фыглядит эта функция.
UNI>
UNI>Абсолютно ничего не изменилось.
Честно говоря, не помню как там fgets работает, но по идее, если ты считываешь 64 байта, то должен быть ещё 65-ый, нулевой. Нет? А то как будет lstrcat работать?
Здравствуйте, UNI_X, Вы писали:
UNI>>>[/ccode]
UNI>Исправил, только эффект тот же. Работает неправильно, файл просто очищается и всё.
UNI>Вот так теперь фыглядит эта функция.
UNI>
UNI>Абсолютно ничего не изменилось.
Ну позанудничаю немножко
Как ты думаешь что будет делать твоя программа когда ей встретится файл с размером больше 1K
Я думаю что она попытается сформировать жалобу дяде Билу
ЗЫ
Что зачеты сдаеш? Чего то рано Или за прошлый семестр хвосты остались
Здравствуйте, Какая разница, Вы писали:
КР>Ну позанудничаю немножко
КР>Как ты думаешь что будет делать твоя программа когда ей встретится файл с размером больше 1K
КР>Я думаю что она попытается сформировать жалобу дяде Билу
КР>ЗЫ
КР> Что зачеты сдаеш? Чего то рано Или за прошлый семестр хвосты остались
Я вам так скажу, что неважно какого размера буфер, 64 или 1024, файл заведомо меньше, и каждая строка меньше 64 байт. Мне бы сделать хотя бы с такими условиями. Вы можете сказать, что в приведенном коде неправильно? В чем ошибка? Если честно, эта функция сама по себе какая-то неправильная, в ней даже MessageBox'ы не срабатывают, ни в конце, ни в начале, нигде вобщем.
Здравствуйте, UNI_X, Вы писали:
Проблема в том, что storyData — пустая строка, а ты пытаешься добавлять к ней другие строки.
Нужно либо заранее сделать ее достаточной длины (например, равной длине файла, если он конечно соответствующего размера), либо динамически выделять под нее память (возможно для этого вычисляется переменная len ), но многократно динамически расширять строку не очень-то хорошо.
И вообще, лучше составить алгоритм иначе.
Здравствуйте, DPavel, Вы писали:
DP>Здравствуйте, UNI_X, Вы писали:
DP>[]
DP>
DP>Проблема в том, что storyData — пустая строка, а ты пытаешься добавлять к ней другие строки.
DP>Нужно либо заранее сделать ее достаточной длины (например, равной длине файла, если он конечно соответствующего размера), либо динамически выделять под нее память (возможно для этого вычисляется переменная len ), но многократно динамически расширять строку не очень-то хорошо.
DP>И вообще, лучше составить алгоритм иначе.
А иначе это как? Можно поподробнее, интересно!?
Здравствуйте, UNI_X, Вы писали:
UNI>А иначе это как? Можно поподробнее, интересно!?
Можно создать временный файл функцией tmpfile() и в него копировать те строки, которые нужно оставить. После просмотра исходного файла скопировать в него всю информацию из временного файла. rmtmp() удаляет все временные файлы.
Но лучше использовать представленный тобою алгоритм, но только исользовать тип string. Тогда можно было бы добалять к строке этого типа строки из файла, не заботясь о длине строки. Это было бы, пожалуй, лучшим вариантом.
C++: как удалить последнюю пустую строку из файла?
C++: как удалить последнюю пустую строку из файла?
За числом 10 следует пустая строка. Имеется ли возможность задать в коде программы её (пустой строки) удаление?
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.
© Г. Уэллс "Человек-невидимка"
Пустых строк не бывает. Если строка пустая — значит её нет. Если она есть — значит в ней должен быть как минимум завершающий символ перевода строки.
По идее у Вас должен был получиться файл такого содержания: "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n". Содержащий 10 строк. Что-то не так?
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
За числом 10 следует пустая строка. Имеется ли возможность задать в коде программы её (пустой строки) удаление?
За числом 10 следует символ перевода строки (\n). Вы его хотите удалить? На последнем шаге просто уберите endl.
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
За числом 10 следует символ перевода строки (\n). Вы его хотите удалить? На последнем шаге просто уберите endl.
Хорошо бы при этом ещё отдавать себе отчёт, зачем это надо. Так делать не принято, и многие программы просто проигнорируют строку, не завершённую \n, а то и заглючат при чтении такого файла.
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Пустых строк не бывает. Если строка пустая — значит её нет. Если она есть — значит в ней должен быть как минимум завершающий символ перевода строки.
По идее у Вас должен был получиться файл такого содержания: "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n". Содержащий 10 строк. Что-то не так?
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.
© Г. Уэллс "Человек-невидимка"
Ну откройте тот же файл в vim, там будет не так. Это просто особенность данного конкретного текстового редактора.
Или подсчитайте число строк с помощью wc -l и убедитесь, что их десять.
Или, наконец, посмотрите содержимое файла с помощью hexdump -C .
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
AkelPad. Когда скриншот делал, не было под рукой линукс-ПК.
Ну откройте тот же файл в vim, там будет не так. Это просто особенность данного конкретного текстового редактора.
Или подсчитайте число строк с помощью wc -l и убедитесь, что их десять.
Или, наконец, посмотрите содержимое файла с помощью hexdump -C .
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.
© Г. Уэллс "Человек-невидимка"
Давайте прикинем. Сперва у Вас есть файл "ровно" с n-ю строками. В конце последней строки не стоит символ сброса (\n) -- как гововрили выше, это может быть плохо по различным причинам. Во-первых, поймут не все парсеры. Во-вторых, при автоматическом дописывании новых строк первая из них склеится с последней из имевшихся.
Теперь добавим в конец символ \n. С точки зрения содержимого файла новой строки не будет, мы лишь завершим старую по общепринятому стандарту. С точки зрения GUI редактора мы, набрав последние символы в n-й строке, нажали клавишу Enter, то есть перешли на n+1-ю. Но, пока там нет ни одного символа -- это не совсем строка, а некий "placeholder", в который можно только поставить курсор. Показывать ли его как строку с новым номером -- вопрос субъективный. Для большинства пользователей привычнее, если да.
За числом 10 следует символ перевода строки (\n). Вы его хотите удалить? На последнем шаге просто уберите endl.
Я исхожу из того, что ТС понимает что делает. Возможно он добавляет к этой строке еще что-то, вызывая либо следующую функцию, либо другую программу. Пример, приведенный тут, наверняка изменен.
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Может кто-нибудь сказать мне, как я могу добиться того, чего я хочу. Извините, у меня еще нет кода. Если вы дали мне несколько примеров, я действительно ценю это.
data.txt:
Lorem Ipsum — просто фиктивный текст в полиграфии и вёрстке.
Lorem Ipsum был стандартным фиктивным текстом в индустрии с 1500-х годов,
когда неизвестный prindfdtersd взял камбуз типа и скремблировал его, чтобы сделать образец типа
книга. Он пережил не только пять веков, но и скачок в электронику
набор текста, оставаясь практически без изменений. Он был популяризирован в 1960-х годах с
выпуск листов Letraset, содержащих отрывки Lorem Ipsum, а в последнее время и настольных
Публикация программного обеспечения, такого как Aldus PageMaker, включая версии Lorem Ipsum.
% 12345
Решение
Если вы хотите, чтобы код был на 100% переносимым, все, что вы можете сделать, — это прочитать весь текст и построчно скопировать его, оставив последнюю строку. Если реальный файл такой же маленький, как пример в вопросе, вы можете просто пойти с этим.
Если файл большой и вас не волнует абсолютная переносимость, вы можете довольно легко найти точку размером около 4 килобайт с конца и начать чтение с нее. Когда вы выясните, где начинается последняя строка, используйте метод, специфичный для платформы, чтобы обрезать файл до этой точки (SetEndOfFile в Windows, выполнить поиск правильной точки и выполнить запись нулевой длины в UNIX и т. Д.)
Что касается имеющегося кода, по крайней мере, если вы пытаетесь сделать это с помощью достаточно современного компилятора C ++, вам, вероятно, нужно выбросить этот код и начать все сначала. Я знаю, это звучит грубо, и мне очень жаль, но в этом случае это правда. Давайте начнем с заголовков— а также были устаревшими с середины 1990-х или около того, пару десятилетий назад. Большинство современных компиляторов будут отклонять код только на этой основе.
Оттуда ваш код для чтения данных фатально испорчен почти во всех отношениях. Форма std::getline вы все еще технически включены в C ++, но это было хорошее десятилетие, так как оно использовалось достаточно часто, чтобы заметить. Вы почти всегда хотите форму, которая принимает std::string параметр. Ваше состояние цикла ( while(!inFile.eof()) ) также полностью сломан — это в значительной степени не может работать правильно.
Что касается того, как я это сделаю, я бы, вероятно, сделал что-то в этом общем порядке:
прочитайте файл, удалите строку в памяти и поместите содержимое обратно в файл (перезапись). Если файл большой, вы можете прочитать его строку за строкой и создать временный файл, позже заменив исходный.
на очень большие файлы, я бы сделал что-то вроде этого
обновление я изначально написал это еще в 2009 году и я думал, что это может быть интересно с обновлением. Сегодня вы можете выполнить вышеуказанное, используя LINQ и отложенное исполнение
код выше почти точно такой же, как в первом примере, читая строку за строкой и сохраняя минимальный объем данных в памяти.
A отказ от ответственности может быть в порядке. Поскольку мы говорим о текстовых файлах, вам очень редко придется использовать диск в качестве промежуточного носителя. Если вы не имеете дело с очень большими файлами журналов, не должно быть никаких проблем с чтением содержимого в память и избежать необходимости иметь дело с временным файлом.
отметим, что .ToList имеет решающее значение здесь, чтобы заставить немедленное исполнение. Также обратите внимание, что все примеры предполагают, что текстовые файлы кодируются UTF-8.
- читать весь файл в память (например, File.ReadAllLines )
- удалите оскорбительную строку (в этом случае, вероятно, проще всего преобразовать массив строк в List затем удалить строку)
- напишите все остальные строки назад (например, с File.WriteAllLines ) - потенциально преобразовать List в массив строк снова с помощью ToArray
это означает, что вы должны знать, что у вас есть достаточно памяти, хотя. Альтернатива:
- Откройте как входной файл, так и новый выходной файл (как TextReader / TextWriter , например, File.OpenText и File.CreateText )
- читать строки ( TextReader.ReadLine ) - если вы не хотите удалять его, напишите в выходной файл ( TextWriter.WriteLine )
- когда вы прочитаете все строки, закройте как считыватель, так и писатель (Если вы используете using заявления для обоих, это произойдет автоматически)
- если вы хотите заменить вход на выход, удалите входной файл, а затем переместите выходной файл на место.
я расширил то, что предложил Маркус Олссон, и придумал этот класс, который добавляет несколько строк поиска и пару событий:
чтобы удалить элемент из текстового файла, сначала переместите весь текст в список и удалите нужный элемент. Затем запишите текст, хранящийся в списке, в текстовый файл
Я бы очень просто:
- открыть файл для чтения/записи
- читать / искать через него до начала строки, которую вы хотите удалить
- установите указатель записи на текущий указатель чтения
- прочитайте до конца строки, которую мы удаляем, и пропустите разделители новой строки (считая количество символов, когда мы идем, мы назовем его nline)
- читать байт за байтом и записывать каждый байт в файл
- когда закончите усечь файл до (orig_length-nline).
Привет, ребята, я написал метод удаления строк из файлов. Эта программа использует using System.IO
Я хочу удалить некоторые n строк из конца файла. Можно ли это сделать с помощью sed?
например, чтобы удалить строки от 2 до 4, я могу использовать
но я не знаю номера строк. Я могу удалить последнюю строку, используя
но я хочу знать, как удалить n строки с конца. Пожалуйста, дайте мне знать, как это сделать, используя sed или какой-либо другой метод.
Я не знаю sed , но это можно сделать с помощью head :
Кажется, то, что вы ищете.
забавный и простой sed и tac устранение :
Примечание
- двойные кавычки " необходимы для оболочки для оценки $n переменная
Если hardcoding n является опцией, вы можете использовать последовательные вызовы sed. Например, чтобы удалить последние три строки, удалите последнюю строку трижды:
использовать sed , но пусть оболочка делает математику, с целью использования d команда, давая диапазон (чтобы удалить последние 23 строки):
удалить последние 3 строки, изнутри:
дает количество строк файла: say 2196
мы хотим удалить последние 23 строки, поэтому для левой стороны или диапазона:
выдает: 2174 Таким образом, оригинальный sed после оболочки толкование:
С -i делать inplace edit, файл теперь 2173 строки!
можно использовать глава для этого.
$ head --lines=-N file > new_file
где N-количество строк, которые вы хотите удалить из файла.
содержимое исходного файла минус последние N строк теперь находятся в new_file
просто для полноты, я хотел бы добавить мое решение. Я закончил тем, что сделал это со стандартным ed :
этого удалить последние 2 строки, используя редактирование на месте (хотя это тут использовать временный файл в /tmp !!)
Это может сработать для вас (GNU sed):
для усечения очень больших файлов действительно на месте у нас есть . Он не знает о линиях, но tail + wc можно конвертировать строки в байты:
существует очевидное условие гонки, если файл записывается одновременно. В этом случае может быть лучше использовать head - он подсчитывает байты с начала файла (mind disk IO), поэтому мы всегда будем усекать на границе строки (возможно, больше строк, чем ожидалось, если файл активно записывается):
удобный один-лайнер, если вы не войти попытка поставить пароль вместо имени пользователя:
с ответами здесь вы бы уже узнали, что sed не лучший инструмент для этого приложения.
однако я думаю, что есть способ сделать это с помощью sed; идея состоит в том, чтобы добавить N строк, чтобы удерживать пространство, пока вы не сможете читать, не нажимая EOF. При попадании в EOF распечатайте содержимое hold space и завершите работу.
команда sed выше опустит последние 5 строк.
Читайте также: