![]() |
|
|
![]()
|
|
| 3315720 |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 28.2.2008 Репутация: нет Всего: нет |
Здравствуйте. Неожиданно возникла проблема. Есть структура примерно такого вида:
Которую я записываю в файл.
И затем считываю из файла
Так вот пока длина строк менее 32, все отлично. Но как только они достигают полного размера начинают слипаться. т.е. считываются соседние строки за пределом буфера. Получается примерно так: String1[32] = строка1строка2строка3\x16 String2[32] = строка2строка3\x16 String3[32] = строка3\x16 Так вот вопрос как ограничить чтение из буфера без применения нуль-терминированной строки. Очень неохото вставлять 33й символ конца строки. Файл бинарный и считывается только моей прогой а не блокнотом. Лишние символы не нужны. Вот еще этот символ \x16 прилепляется к последней строке. Он также находится за пределами буфера но CodeGuard не фиксирует никакого выхода нигде.... Это сообщение отредактировал(а) 3315720 - 16.6.2012, 22:48 |
||||||
|
|||||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Я бы сделал так:
читал/писал структуру не целиком, а по отдельным параметрам. Причём, для строк, первый байт - это длина строки. Так будет даже правильней, т.к. вы писали: Просто в вашем случае, получается так, что даже если строка имеет длину 5 символов, в файл всё равно запишется 32 (остальное будет мусор). Поэтому, ИМХО, мой способ самый верный в данной ситуации. Причём, при чтении структуры целиком могут возникнуть проблемы с выравниванием в разных средах разработки. Это сообщение отредактировал(а) artsb - 16.6.2012, 21:49 -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| 3315720 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 28.2.2008 Репутация: нет Всего: нет |
В строки по любому нужно встраивать \0, иначе без разницы. Длина строки в файле не критична, повторюсь файл не текстовый, а бинарный. Мне не нужно бить его на строки вставляя непечатные символы. Даже не читая и не записывая, а просто присвоив строкам значения длинной 32 к ней прилипает следующая строка. И такая конструкция
Присвоит строке а значение "строка1строка2строка3\x16". Проблема не в считывании/записи файла, а в считывании из оперативной памяти. замена char[32] на AnsiString[32] решает проблему, но насколько это правильно и чем может грозить? К тому же возникли ошибки при удалении экземпляров структур при char[32] четко срабатывал new и delete, а при AnsiString[32] - delete вызывает "access violation..." и "abnormal program termination" (аварийное завершение программы). Это сообщение отредактировал(а) 3315720 - 16.6.2012, 22:52 |
|||
|
||||
| 3315720 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 28.2.2008 Репутация: нет Всего: нет |
Еще немного пищи для ума...
Простой пример демонстрирующий происходящее.
|
|||
|
||||
| artsb |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Ну да, нулевой байт нужен. А как иначе определить длину строки. Кстати, в вашем примере последнем, ни в коем случае нельзя копировать строки таким образом:
Хотите вы или нет, но функция strncpy() добавит в конец нулевой символ. А значит вылезет за пределы доступной памяти и подпортит что-нибудь. Если уж очень нужно, то копируйте с помощью memcpy()
Ну и "доставать" эту строку придётся с помощью memcpy(), т.к. все функции для работы со строками требуют, чтобы в конце был ноль. Но я не вижу смысла так заморачиваться из-за одного несчастного нулевого байта в конце. Это сообщение отредактировал(а) artsb - 17.6.2012, 13:04 -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||||
|
|||||||
| 3315720 |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 28.2.2008 Репутация: нет Всего: нет |
strncpy никуда не вылазит, самостоятельно ничего не пишет. Что и демонстрирует пример. http://ru.wikipedia.org/wiki/Strncpy Вы видимо спутали strncpy с strlcpy, последняя как раз таки следит за тем чтобы ноль обязательно был в конце. strcpy вообще ни зачем не следит и запросто выходит за пределы буфера. Может есть вариант бинарного хранения символов не в char, а как-то еще? Меня вполне устроит какой-нибудь Buffer длинной 32 байта. П.С. memcpy не решает проблему. Видимо такова реализация char. как вариант я вижу ручной перебор символов, что бы не вылазить за пределы при чтении или терминатор "\0". Первое это маразм. Прийдется всетаки вводить 33й байт.... Это сообщение отредактировал(а) 3315720 - 17.6.2012, 16:09 |
||||
|
|||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Так у вас и так буфер используется. Просто вы не хотите ставить нулевой символ в конце. Но все функции из стандартной библиотеки написаны с таким расчётом, что в конце должен быть нулевой байт. Так что, какой бы тип буфера вы не использовали, у вас не получится использовать ваши "строки" в стандартных функциях. Придётся писать что-то своё. Кстати, можно написать не структуру, а класс и перегрузить для него операции ввода/вывода. Но опять таки, тут возникает проблема - а что если длина строки будет меньше 32? Как вы будете определять длину строки, чтобы произвести с ней операции? Конечно, можно сделать так: При инициализации структуры/класса всегда все строковые переменные обнулять полностью. делать тоже самое при изменении строки. Далее, при обращении к строке, делать проверку - если последний байт равен 0, то считать, что строка имеет длину меньше 32 символов, иначе - ровно 32. И уже во втором случае, будете работать со строкой через strncpy() Но лучше, ИМХО: -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| 3315720 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 28.2.2008 Репутация: нет Всего: нет |
||||
|
||||
![]()
|
| Правила форума "С++ Builder" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C++ Builder | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |