Функция-загадка
Что делает эта функция?
{
while(*s++ = *p ++);
}
По идее, она копирует в строку s строку p. Но, во-первых, каков критерий выхода из цикла? -> И сколько скопируется символов в итоге?
Тролль?
grgdvo
Я то же самое ответил, ответили, сказали "ну, пойдемьте дальше", т.е. типа это неверно. Еще есть варианты?
классика :) критерий while (TRUE)
"Пока s можно присвоить p" ?
char p[30]="pbpbpb";
func(s,p);
printf("%s\n%s", s, p);
в s выводит pbpbpb. Код небезопасен получается, а мне сказали, что в такой код, возможно и есть самый лучший в плане копирования строк. Не понимаю, где меня нае..
+100
а что он должен вывести по твоему?
а) вы работаете только с null-terminated строками; либо
б) для каждой строковой операции вы задаете размер буфера.
Второй вариант, очевидно, лучше и безопаснее. Сказали вам абсолютно правильно: если давать вашей функции буфера правильного размера, то такой способ копирования действительно самый короткий. А в принципе, кривыми руками можно самый безопасный код сделать небезопасным. Если вы посмотрите на вашу функцию, вы увидите, что она выполняется не до тех пор, пока *s != 0, а до тех пор, пока *p != 0. Поэтому если вы заведомо делаете длину s меньше длины p, то вам может повезти, а может и не повезти.
а что он должен вывести по твоему?
Извините, тупой вопрос. Или тоже троллинг? Я, во-первых, не спрашивал, что он выведет. Во-вторых, это предложение связано со вторым, а ты вынул его из контекста. Ты книги тоже раз через 50 страниц читаешь?
Короче, все ясно. Тут все такие "перцы", что легче на всяких двачах для идиотов спрашивать, чем здесь. Пара человек-адекватов находится и все.
А как по вашему можно узнать размер буфера, если сюда переданы только указатели? Александр правильно сказал, в C такие строковые операции используют либо длину буфера, передаваемую отдельно, либо ориентируются на завершающий ноль и на то что памяти в принимаемом буфере достаточно (программист проверил это через strlen). Функция в примере фактически полный аналог стандартной и общеизвестной функции strcpy - именно так она и работает. Так уж повелось исторически, подобные функции изобилуют в C с древних времен.
И я не знаю где вы там увидели троллинг у меня или кота - лично я был абсолютно серьезен. Вы задаёте вопросы, которые относятся к основам языка. Не зная которых не возможно нормально им пользоваться. Не стоит, прочитав не приятную вам информацию, сразу кидаться и отрицать. Лучше прислушаться - тут не тот форум, где троллят.
Вы знаете абсолютно все заковырки?
Да и я все время использовал strncpy, считая это более правильным, хотя и менее(в теории) производительным. Хелп в си я уже не помню, т.к. в борланде уже 4 года не ковырялся.
Плюс ко всему, когда знаешь/изучаешь много языков, в старом что-то можешь забыть или напутать. Не приходило в голову такое, или Вы только C++ знаете? Нет, нужно сразу сказать, что я еще ребенок и пора мне в ясельках на годик остаться. Спасибо. И вообще, знаете-ли, как бы это глупо и обидно ни звучало, но я Вас не спрашивал -> Ваш пост - оффтоп. И напоследок, - если Вы знаете, что можете обидеть человека каким-то словом/фразой/словосочетанием - то ЗАЧЕМ это говорить?
Вы знаете абсолютно все заковырки?
Да и я все время использовал strncpy, считая это более правильным, хотя и менее(в теории) производительным. Хелп в си я уже не помню, т.к. в борланде уже 4 года не ковырялся.
Плюс ко всему, когда знаешь/изучаешь много языков, в старом что-то можешь забыть или напутать. Не приходило в голову такое, или Вы только C++ знаете? Нет, нужно сразу сказать, что я еще ребенок и пора мне в ясельках на годик остаться. Спасибо. И вообще, знаете-ли, как бы это глупо и обидно ни звучало, но я Вас не спрашивал -> Ваш пост - оффтоп. И напоследок, - если Вы знаете, что можете обидеть человека каким-то словом/фразой/словосочетанием - то ЗАЧЕМ это говорить?
1. \0 на конце вводить не надо, когда вы пишете двойные кавычки, он автоматически добавляется в конец.
2. Вы считаете "заковырками" стандарты, описанные в любой литературе?
aks, я прошу прощения, если я ответил за вас. Возможно, последний пост был адресован лично вам. :)
Вот еще вопрос, к Вам, таким умникам: почему просто нельзя ответить на вопрос, а куда-то посылать, как Евреи? Вы русские? Хотя...
По завершающему нулю определяется лишь конец копируемой строки.
Вы знаете абсолютно все заковырки?
В С нету "заковык". В С++ есть, могу предположить что какие то не знаю. Хотя не факт. Но это не "заковыка". Это основы языка. Это конструкция которую надо понимать прежде чем хоть как то пользоваться языком.
Да и я все время использовал strncpy, считая это более правильным,
Более безопасным, да.
хотя и менее(в теории) производительным.
Нисколько не менее. Хоть в теории, хоть на практике.
Вы только C++ знаете?
Я знаю много языков программирования. Причем порой совершенно не похожих на С. Но если я пойду на собеседование, где будут спрашивать по С - надо хоть не много разбираться в нем, разве нет? Если вы не знаете основ - туда идти не надо! Именно это я и хотел сказать и не понимаю, почему у вас такая неадекватная реакция и оправдания, вместо того чтобы прислушаться и спокойно прочитать ответы на вопрос.
почему просто нельзя ответить на вопрос,
На ваш вопрос ответили неоднократно в этой теме.
Т.е. Ты считаешь своим долгом выставить свое гражданское мнение по поводу того, как у меня складывается жизнь? Не думаешь ли ты, дорогой, что твое мнение никого не интересовало? Тем-более уж, если мне ответили на вопрос?
Знаете? Прям всем 100%? И все вспомните прям, если Вас расспрашивать начнут? Во-первых, основы у меня те, что положило мне образование. Во-вторых, раз уж Вы действительно такой умный, а я такой дурак, то ПОЧЕМУ Вы, уважаемый, не сказали мне где об этой основе можно прочитать? Не думали ли Вы, что я что-то мог забыть или перепутать вследствие годичного-двухгодичного использования абсолютно другого языка(по-моему я уже где-то это писал, не?)?
Почему человек выше смог это сделать, не высказывав свое мнение по поводу чего-то в моей жизни и так далее, а Вам(да Вы, наверное, Бог!) прям следовало это сделать?
У меня к вам только один вопрос (хотя не считаю себя "таким умником"): вы Кернигана и Ритчи читали? Тот самый пример, из-за которого здесь возник спор, там расписан по пунктам. Если не читали - следовательно, вас нужно послать почитать. Если читали - следовательно, вас нужно послать перечитать! Я ответил на ваш вопрос?
Стыдно признаться, но у меня валяется Страуструп, купленный 4 года назад, который я в то же время и читал. Поэтому, много забыл, возможно. 1000 страниц с чем-то за день не прочитаешь и не освежишь в памяти, как произошло в моем случае.
Кернигана и Ритчи нет у меня, к сожалению. Советуете?
и с чего она "пойдет дальше по стеку"?
вот именно что Страуструп "валяется". Иначе вопросов бы не возникло.
ПыСы. Меня всегда удивляла агрессивность недообразованщины. Допустить возможность того, что оно что то не знает - данибожежш мой. Книжки млять толстые - вот кто виноват. КНИЖКИ ТОЛСТЫЕ. КИСО НЕАСИЛИЛО! :D
Да, валяется. Я думал, на форуме можно не только хвалиться "ох, какой я вопрос очешуенный нашел! Давайте все думать!", но и приобрести знания, что-то спросить и получить ответ на свой вопрос. Ан нет оказывается. Ладно, буду знать, большое спасибо.
И дело не в том, что я что-то не знаю, а в (том, что я задал вопрос, а мне вместо ответа на него пишут какой-то бред) (-выделил скобками для ясности мысли).
Да, я не знал, и именно, черт возьми, поэтому я открыл этот форум и написал сюда. В ЧЕМ ПРОБЛЕМА? Это не входит в правила форума? Или форумы созданы для чего-то другого? Что за бред вы говорите? Почему Я не могу чего-то спросить у Вас? Вы такие все звезды? Напоминает фразу "Я дартаньян, а вы все пи...".
Я вот еще одну вещь не пойму никак - раз Вы все такие умные, все знаете, то почему же Вы грамотно только о жизни рассуждаете, а об ответе на вопрос ни слова? Выходит, не знаете? Да нет же. Похоже, Вам просто нужно где-то высказаться и назвать человека не знающим, чем помочь ему и объяснить, в чем же он не прав. Если бы нас так учили, то все рекурсивно в первый класс переходили.
Откуда здесь взяться переполнению буфера? Разве в приведенном участке выполняется доступ к памяти? Происходит выделение блоков памяти? Указатель указывал на одну область в памяти, потом стал указывать на другую, причем которая реально существует и память под которую выделена - это гарантируется. Все. что здесь опасного? Возьми страуструпа и посмотри - даже страницу бы тебе сказал - но не могу - нахожусь в прекрасной стране Беларуси - тут знаешь ли страуструпы по номерам не валяються.
Откуда здесь взяться переполнению буфера? Разве в приведенном участке выполняется доступ к памяти? Происходит выделение блоков памяти? Указатель указывал на одну область в памяти, потом стал указывать на другую, причем которая реально существует и память под которую выделена - это гарантируется. Все. что здесь опасного? Возьми страуструпа и посмотри - даже страницу бы тебе сказал - но не могу - нахожусь в прекрасной стране Беларуси - тут знаешь ли страуструпы по номерам не валяються.
Во-первых, "кисо" оставь для свой домашних питомцев или для своей ненаглядной. Или ты тоже будешь говорить, что этим словом ты "заботишься" и обзываться такими словами гуманно? Мда.
Во-вторых, насчет буферов. Да, был не прав, затупил. И сейчас, к твоему удивлению, я не читал книгу, а просто твои слова меня натолкнули на мысль, что мы же указателю присваиваем адрес, а не изменяем по его адресу значение. Всего-то, требовалось эти слова хотя б просто заспамить на первой странице. Неужели правда нужно было оффтопить и разводить на три? Вот теперь без сарказма, спасибо.
Стыдно.. Ходил, тупил два дня. Ну ладно. Я болею, мне можно (c).
а по поводу того, что на три страницы - ну так кто тебе доктор что ты три страницы тупил? :) (тем более что у меня кстати только одна).
Тебе сразу сказали - в в пятом посте от terrs. Не знаю правда понял ли он сам это (похоже что не очень), но то что ты наконец то понял это к 23 сообщению в теме - это уже не плохо. т.е. какой то шаг к пониманию как это работает ты для себя сделал. Ты считаешь что лучше бы и понятней что бы тебе это разжевали? запишись на курсы. :)
Да ты толком и не сказал ничего, лишь завел мне моск на тему адресов. Я почему-то думал, что работа со значениями, а она, что абсолютно очевидно, - с указателями. В общем, тупости нет предела :)
Очень извиняюсь и прошу прощения. Как видите, дело было в дичайшей невнимательности ввиду температуры(:(), а не в не знании.
Какую-то херню вы все тут развели на 25 сообщений.
Заинтриговал. Поделишься?
[quote=strcpy]
To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.
[/quote]
[COLOR="silver"]Чтобы предупредить переполнение, размер массива, указанный в назначении, должен быть достаточным для вмещения такой же строки что и источник (включая заканчивающий символ 0 ), и не должен пересекаться в памяти с источником.[/COLOR]
За этим имхо должен следить программист ещё при кодинге.
Итак.
using std::cout;
void func(char *s, const char *p)
{
while(*s++ = *p++);
}
int main()
{
char s[5]="lal";
char p[30]="pbpbpb";
func(s,p);
cout <<"\n"<<&s<<"\n"<<&p;
return 0;
}
Объявляем и инициализируем char s[5]="lal"; Соответственно, теперь строка принимает вид "lal\0". То же самое делаем с p: char p[30]="pbpbpb"; Здесь мы выделили строго отведенный участок памяти, соотвественно, выйдя за его пределы, можно легко эксплойтиться. Почему? Потому, что никакой проверки там нет и цикл while будет работать до тех пор, пока не закончится второй указатель(p) в данном случае, абсолютно наплевав на первый (s) и на его длину. Соответственно, переполнение буфера здесь ИМЕЕТ место быть и не нужно меня тут путать, что мы присваиваем здесь указателю другой адрес. Я специально на следующий день(наверное отходняком от предыдущего) вспомнил вчерашний свой пост где с этим согласился и у меня выпали глаза(шутка, конечно). Думаю, как я мог сказать такую тупость и как ее могли сказать мне?(!). На всякий случай уж, решил проверить:
cout <<"\n"<<s<<"\n"<<p;
s и p указывают абсолютно на разные адреса, так что не нужно мне тут говорить о присвоении адресов. Да и вообще это бред. Раз это КОПИРОВАНИЕ строк, то какое нахрен присвоение адресов? Цель копирования - получить абсолютно идентичную строку по содержанию и размерам, как у исходной.
Извините, поправьте, если я опять(!??) где-то ошибся.
Upd: если хотите какую-нибудь простейшую проверку "на лету", то это что-то типа
{
while(*s && (*s++ = *p++));
}
Вы вобще читаете что вам пишут? такое чувство что нет. Повторю в который раз. Есть два варианта работы с C строками:
1) определять размер копируемой строки по завершающему нулю. Естественно в данном случае буфер куда копируется должен быть соответствующих размеров. За этим следит программист, который буфер выделяет.
2) Явно задается размер буфера, куда будет скопирована строка. При этом конечно же никто так же не гарантирует, что буфер будет того же размера, который передали. Это так же на совести программиста.
Где вы там увидели присваивание указателей - ума не приложу. Там просто поэлементное копирование строк. И это как раз те основы языка, которые не раз упоминались.
Где вы там увидели присваивание указателей - ума не приложу. Там просто поэлементное копирование строк. И это как раз те основы языка, которые не раз упоминались.
aks, :facepalm:
Я вам и говорю, что никакого присваивания указателей здесь нет, однако один человек с ником kot мне это утверждал несколькими постами выше.
И какие там основы языка? Что вы мне тут говорите? Это я азов языка не знаю? Тогда что вообще kot знает о нем? Вы меня тут за идиота держите, по ходу.
Вот вы сами посудите - язык один, правильных ответов может быть тоже только один - а у вас тут их уже наверное за 3 зашло. Ну и кто из вас прав, а?
И я не говорю, что мне нужно реализовать проверку размеров строк и не спрашивал это. Я лишь говорю, что в этом коде этого нет - и все. С чего вы вообще взяли, что я у вас спрашивал про проверку размеров строк в этом коде? Я ясно сказал, что ее здесь нет и все. Ваш комментарий - абсолютно неуместен. Такое ощущение, что это Вы не читаете, что пишут, а сразу лезете со своими мыслями.
И еще: Вы - узколобый человек. Вы так сильно заостряете внимание на том, что я написал здесь этот простой вопрос(с целью получения подтверждения моего мнения) и сделав вывод, что я никудышный незнайка, что даже не читаете теперь моих постов и несете какой-то бред(например, читайте выше - про размеры строк). ГДЕ Я вас это спрашивал? Конечно, понимаю, по-вашему я настолько тупой, что не додумаюсь определить размеры массива. :facepalm:
Alexandr92
Я, конечно, понимаю, что Вы тоже очень "образованный сишник", тру-кодер и так далее, однако, опять же, где я спрашивал о том, как и где можно определить размер? Ткните пальцем.
Я, конечно, понимаю, что Вы тоже очень "образованный сишник", тру-кодер и так далее
А давайте не будем переходить на личности, хорошо? Когда я писал про "необразованных сишников", я не имел в виду вас, и не имею в виду себя под "образованными".
опять же, где я спрашивал о том, как и где можно определить размер? Ткните пальцем.
Я не изучал наизусть историю ваших постов. Я всего лишь ответил, как решать вашу задачу правильно. Я не знаю вас лично, поэтому я не буду ничего говорить о вашей грамотности или неграмотности, но, извините меня, реагируете вы сейчас действительно не вполне адекватно.
Вот скажите мне, какой толк от форума, если мы здесь написали 4 страницы и мне все равно пришлось сесть самому и все изучать? Не исключаю, это мне только на руку, однако же, зачем форум, если на нем не помогают?
Наверное, потому что ни один форум не поможет до тех пор, пока не сесть и не изучить. :) Форум годится в двух случаях: а) когда возникает маленький конкретный вопрос, или б) направление дальнейшего движения не понятно в принципе, и человек просит совета, куда ему двигаться. Использование форума в других целях в 99.9% случаев приводит к таким оффтопам (хотя на самом деле, оффтопа в этой теме не так много).