C массив строк char

Для char [] Я могу легко получить его длину:

Тем не менее, я не могу сделать так, чтобы получить длину char * от:

потому что я знаю, a вот указатель, такой что length здесь всегда будет 4 (или что-то другое в разных системах).

Мой вопрос заключается в том, как я могу получить длину char * после этого? Я знаю, что кто-то может бросить мне вызов, что вы уже знаете его 10 потому что вы только что создали это. Я хочу знать это, потому что этот шаг получения его длины может пройти долгий путь от его создания, и я не хочу возвращаться далеко назад, чтобы проверить это число. Кроме того, я также хочу знать его реальную длину.

Чтобы быть более конкретным

  • как я могу получить его реально length=5 ?
  • как я могу получить его общее length=10 ?

для следующего примера:

Решение

Ты не можешь Во всяком случае, не со 100% точностью. Указатель не имеет длины / размера, но имеет свои. Все, что он делает, это указывает на определенное место в памяти, которое содержит символ. Если этот символ является частью строки, то вы можете использовать strlen определить, какие символы следуют за указанным в данный момент, но это не означает, что массив в твоем случае такой большой.
В принципе:

указатель это не массив, так что это не необходимость знать, каков размер массива. Указатель может указывать на одно значение, поэтому указатель может существовать, даже не будучи массивом. Его даже не волнует, где находится память, на которую он указывает (только чтение, куча или стек … не имеет значения). Указатель не имеет длины, отличной от себя. Указатель просто …
Учти это:

Указатель может быть одним символом, а также началом, концом или серединой массива …

Думайте о символах как о структурах. Иногда вы выделяете одну структуру в куче. Это также создает указатель без массива.

Используя только указатель, определить, на какой массив он указывает, невозможно. Самое близкое, к которому вы можете добраться, это использование calloc и подсчет количества последовательных символов 0, которые вы можете найти через указатель. Конечно, это не сработает, если вы присвоили / переназначили материал для ключей этого массива, и это также даст сбой, если память просто вне массива случается держать , тоже. Поэтому использование этого метода ненадежно, опасно и просто глупо. Не. Делать. Это.

Еще одна аналогия:
Думайте о указателе как о дорожном знаке, он указывает на Город Х. Знак не знает, как выглядит этот город, и не знает и не заботится (или может не заботиться) о том, кто там живет. Это работа, чтобы сказать вам, где найти Город Х. Он может только сказать вам, насколько далеко этот город, но не насколько он большой. Эта информация считается неактуальной для дорожных знаков. Это то, что вы можете узнать, только взглянув на сам город, а не на дорожные знаки, указывающие вам его направление

Итак, используя указатель, вы можете только:

Но это, конечно, работает, только если массив / строка заканчивается 0.

В качестве помощника:

на самом деле присваивает size_t (возвращаемый тип sizeof ) для int Лучше всего написать:

поскольку size_t тип без знака, если sizeof возвращает большие значения, значение length может быть что-то, чего ты не ожидал …

Другие решения

Если char * 0-терминатор, вы можете использовать strlen

В противном случае невозможно определить эту информацию.

Есть только два способа:

Если указатель памяти на ваш char * представляет строку C (то есть, она содержит символы, которые имеют 0-байт, чтобы отметить его конец), вы можете использовать strlen(a) ,

В противном случае вам нужно где-то хранить длину. На самом деле указатель указывает только на один char , Но мы можем обращаться с ним так, как будто он указывает на первый элемент массива. Поскольку «длина» этого массива неизвестна, вам нужно где-то хранить эту информацию.

Учитывая только указатель, вы не можете. Вы должны будете держать длину, которую вы прошли new[] или лучше используйте std::vector чтобы следить за длиной, и освободить память, когда вы закончили с ним.

Примечание: этот ответ касается только C ++, но не C.

Просто используйте std::vector которые сохраняют (динамический) размер для вас. (Бонус, управление памятью бесплатно).

Или же std::array которые сохраняют (статический) размер.

Создайте структуру для хранения информации, например:

Мой вопрос заключается в том, как я могу получить длину символа *

Это очень просто. 🙂 Достаточно добавить только одно утверждение

Теперь вы можете получить размер выделенного массива

Многие упоминали здесь C стандартную функцию std :: strlen. Но он не возвращает фактический размер массива символов. Возвращает только размер хранимого строкового литерала.

Разница в следующем. если взять в качестве примера фрагмент кода

тогда std :: strlen (a) вернет 5 вместо 6, как в вашем коде.

Таким образом, вывод прост: если вам нужно динамически выделить массив символов, рассмотрите использование класса std::string , Он имеет размер metaof и длину синонима, что позволяет в любой момент получить размер массива.

Это может звучать как Зло ™, и я не проверял его, но как насчет инициализации всех значений в массиве при выделении ‘’ а затем с помощью strlen() ? Это даст вам ваш так называемый реальная стоимость так как он перестанет считать на первом ‘’ это встречает.

Что ж, теперь, когда я думаю об этом, пожалуйста, никогда не делайте этого. Если только вы не захотите приземлиться в кучу грязной памяти.

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

Вы можете реализовать свой собственный new а также delete функции, а также дополнительный get-size функция:

Кроме того, вы можете переопределить new а также delete операторы аналогичным образом.

Мне нужно сделать массив, содержащий массивы символов (строки). Я сделал как-то так, но меня терзают смутные сомнения. Подскажите, как сделать правильно? Или мой вариант вполне правильный? Память выделять тоже только через Heap, так как программа компилируется без RTL. Можно статически объявлять, главное, чтобы элементы можно было заносить в процессе выполнения.

И сколько места выделять нужно двумерному массиву arr , если 3 массива в нем будет, три?

2 ответа 2

"Корневой" массив содержит указатели. Соответственно, байт под него нужно sizeof(char*) * 3 , если массивов три.

Массивы второго уровня содержат массивы символов с нулём в конце. Соответственно, байт в них должно быть strlen(s) + 1 .

При написании кода arr[0] = "Hello" вы "забываете" прежний указатель, элемент начинает указывать на предвыделенный блок памяти из самой программы. Если вы хотите разместить строку "Hello" в выделенном вами блоке, то можете использовать strcpy .

Учитывая ваш код и вопросы, по-моему, вы рановато избавляетесь от RTL.

Я хотел бы, чтобы преобразовать string to char массив, а не char* . Я знаю, как преобразовать строку char* (через malloc или то, как я разместил его в своем коде) — но это не то, что я хочу. Я просто хочу конвертировать string to char[size] массив. Возможно ли это?

10 ответов:

самый простой способ, который я могу придумать, это:

для безопасности, вы предпочтете:

или может быть таким образом:

хорошо, я в шоке, что никто не дал хороший ответ, теперь моя очередь. Есть два случая;

A константы char массив достаточно хорош для вас так что вы идете с,

или нужно изменить массив символов so constant не в порядке, тогда просто идите с этим

оба всего операций присваивания и большую часть времени это просто что вам нужно, если вам действительно нужна новая копия, тогда следуйте ответам других товарищей.


[an error occurred while processing the directive]
Карта сайта