Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > char*, очистить


Автор: lv151 16.7.2009, 11:38
как правильно  очистить char*?
т.е. чтобы все элементы были "" или '\0'.

Автор: zim22 16.7.2009, 11:47
Цитата(lv151 @  16.7.2009,  11:38 Найти цитируемый пост)
как правильно  очистить char*?

указатель на char очищается так:
Код

char *name = "Hello";
name = NULL;


Цитата(lv151 @  16.7.2009,  11:38 Найти цитируемый пост)
т.е. чтобы все элементы были "" или '\0'.

все элементы? массив указателей на char что-ли?
Код

char *arr[] = { "Hello", "my", "dear", "friend" };

for (int i = 0; i != sizeof(arr) / sizeof(*arr); ++i)
  arr[i] = NULL;

***
или так:
Код

char *arr[] = { "Hello", "my", "dear", "friend" };
memset(arr, 0, sizeof(char*) * (sizeof(arr) / sizeof(*arr)));

Автор: Леопольд 16.7.2009, 13:06
Цитата(zim22 @ 16.7.2009,  11:47)
Цитата(lv151 @  16.7.2009,  11:38 Найти цитируемый пост)
как правильно  очистить char*?

указатель на char очищается так:
Код

char *name = "Hello";
name = NULL;

Не совсем. Это не просто указатель на char а "строковой литерал". name = NULL; - просто перетирает значение указателя и он больше не указывает на область памяти, в которой "лежит" литерал.
Присваивание строковому литералу - undefined behaviour. Т.е. вот так делать нельзя:
Код

char *name = "Hello";
name[0] = '\0';

http://www.cplusplus.com/forum/beginner/11740/

lv151

Если можно пользоваться STL то лучше пользуйся std::string и std::vector
Код

#include <string>
#include <vector>

void print_vector(std::vector<std::string>& v){
    typedef std::vector<std::string>::size_type size_type; //обычно, это то же самое что и size_t
    for(size_type i = 0; i < v.size(); ++i)
        std::cout<<v[i]<<" ";
    std::cout<<std::endl;
}

int main() {
    std::vector<std::string> arr;
    arr.push_back("Hello,");
    arr.push_back("my");
    arr.push_back("dear");
    arr.push_back("friend");
    print_vector(arr);

    arr.erase(arr.begin() + 2); //удалить третий элемент
    print_vector(arr);

    arr.insert(arr.begin() + 2, "real"); //вставить перед третьим элементом
    print_vector(arr);

    arr[2] = "empty"; //тут понятно без комментариев
    print_vector(arr);
}


Автор: mrbrooks 16.7.2009, 13:08
Леопольд, это все замечательно - но если автор имеет ввиду просто С?

Автор: zim22 16.7.2009, 13:12
Цитата(Леопольд @  16.7.2009,  13:06 Найти цитируемый пост)
Присваивание строковому литералу - undefined behaviour. Т.е. вот так делать нельзя

Код

char *name = "Hello";
name[0] = '\0';

я знаю что так делать нельзя. где я так делал?
Цитата(Леопольд @  16.7.2009,  13:06 Найти цитируемый пост)
Не совсем. Это не просто указатель на char а "строковой литерал"

нет. это указатель на константный строковый литерал.

Автор: Леопольд 16.7.2009, 13:14
Цитата(mrbrooks @ 16.7.2009,  13:08)
Леопольд, это все замечательно - но если автор имеет ввиду просто С?

Тут уже надо уточнить у топикпастера.

Добавлено @ 13:17
Цитата(zim22 @ 16.7.2009,  13:12)
...
я знаю что так делать нельзя. где я так делал?

Я и не говорю что ты так делал. А вот lv151 хочет сделать так, сюдя по его вопросу...

Цитата(zim22 @ 16.7.2009,  13:12)
...
Цитата(Леопольд @  16.7.2009,  13:06 Найти цитируемый пост)
Не совсем. Это не просто указатель на char а "строковой литерал"

нет. это указатель на строковый литерал.

Так будет правильнее, не спорю...

Автор: mes 16.7.2009, 13:18
Цитата(Леопольд @  16.7.2009,  12:06 Найти цитируемый пост)
Присваивание строковому литералу - undefined behaviour. Т.е. вот так делать нельзя:

поэтому везде где можно, нужно объявлять как указатель на константу (const char *)

Цитата(zim22 @  16.7.2009,  12:12 Найти цитируемый пост)
я знаю что так делать нельзя. где я так делал?

как я понял, это пояснение Леопольд давал для автора, чтоб он такого не захотел сделать smile

Добавлено через 38 секунд
опоздал.. smile

Автор: Леопольд 16.7.2009, 13:24
Цитата(zim22 @ 16.7.2009,  13:12)
нет. это указатель на константный строковый литерал.

По моему, некоторые компиляторы позволяют такое присваивание. Другие, тоже скомпилируют этот код, но будет ошибка на этапе выполнения, потому что неконстантный строковой литерал будет "лежать" в readonly области. А если использовать char const* lit = "literal" то программа не скомпилируется. О чём уже упомянул mes.

Автор: mes 16.7.2009, 13:27
Цитата(Леопольд @  16.7.2009,  12:24 Найти цитируемый пост)
По моему, некоторые компиляторы позволяют присваивание по char* lit = "literal". 

насколько я слышал, все - из за обратной совместимости с *гладким Си. smile

P.S. *plain C.

Автор: zim22 16.7.2009, 13:32
Цитата(Леопольд @  16.7.2009,  13:24 Найти цитируемый пост)
По моему, некоторые компиляторы позволяют такое присваивание

Цитата(mes @  16.7.2009,  13:18 Найти цитируемый пост)
поэтому везде где можно, нужно объявлять как указатель на константу (const char *)


Автор: Леопольд 16.7.2009, 13:34
Цитата(Леопольд @ 16.7.2009,  13:14)

... А вот lv151 хочет сделать так, сюдя по его вопросу...

Хотя нет, он ведь не объявлял строковой литерал. Он просто спросил как "очистить" char*. Может он память динамически выделил. В общем, вопрос задан плохо, надо задавать уточняющие вопросы. Если я правильно его понял, ему надо сделать что-то вроде этого:
Код

    char* str = new char[length];
    *str = '\0';

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)