char *lower(char *str) {
for(int i=0;i<=strlen(str);i++) {
str = char( tolower(str) );
}
return str;
}
Поиск и замена по строкам - не работает в vc 2010
Сегодня наткнулся на папку проектов vc 2008, посмотрел что за фигню я делал, захотел откомпилировать - ошибка.
В общем к делу:
Код:
В 2008 работало, в 2010 нет
Цитата:
Unhandled exception at 0x00fe1cc3 in ***.exe: 0xC0000005: Access violation writing location 0x00fe88a4.
Код:
char *lower(char *str) {
int len_s = strlen(str); char *ptr;
ptr = (char *)malloc(len_s);
for(int i=0;i<=len_s;i++) {
ptr = char( tolower(str) );
}
return ptr;
}
int len_s = strlen(str); char *ptr;
ptr = (char *)malloc(len_s);
for(int i=0;i<=len_s;i++) {
ptr = char( tolower(str) );
}
return ptr;
}
Но может есть более логичней способ?
Если передавать в первую функцию ссылку на константную строку, то будет выброшено исключение:
Код:
char *source = "SomeText";
lower(source); // exception
lower("SomeText"); // так тоже exception
lower(source); // exception
lower("SomeText"); // так тоже exception
Если сделать так, то всё в порядке:
Код:
char source[] = "SomeText";
lower(source);
// Можно выделить память динамически, через malloc или new
char *source = new char[9]; // "магическое" число лишь для примера
strcpy(source, "SomeText");
lower(source); // тоже всё в порядке
lower(source);
// Можно выделить память динамически, через malloc или new
char *source = new char[9]; // "магическое" число лишь для примера
strcpy(source, "SomeText");
lower(source); // тоже всё в порядке
При этом необязательно в функции возвращать указатель: сама входная строка будет приведена к нижнему регистру.
И ещё: условие i<=strlen(str); вполне можно заменить на i<strlen(str); - нет нужды терминальный нуль приводить к нижнему регистру.
Кстати, Lion, вы неправильно выделяете память под строку:
Код:
int len_s = strlen(str); char *ptr;
ptr = (char *)malloc(len_s);
ptr = (char *)malloc(len_s);
нужно под терминальный ноль место выделить, да и размер char в принципе может быть разным. В итоге получаем:
Код:
int len_s = strlen(str); char *ptr;
ptr = (char *)malloc( sizeof(char) * (len_s + 1) );
ptr = (char *)malloc( sizeof(char) * (len_s + 1) );
нужно под терминальный ноль место выделить
Значит заканчивать надо \0??
Ну вот так:
Цитата:
char *lower(char *str) {
int i; int len_s = strlen(str); char *ptr;
ptr = (char *)malloc(sizeof(char) * (len_s + 1));
for(i=0;i<=len_s;i++) {
ptr = char( tolower(str) );
}
ptr[i++] = '\0';
return ptr;
}
int i; int len_s = strlen(str); char *ptr;
ptr = (char *)malloc(sizeof(char) * (len_s + 1));
for(i=0;i<=len_s;i++) {
ptr = char( tolower(str) );
}
ptr[i++] = '\0';
return ptr;
}
Цитата: Lion__
Значит заканчивать надо \0??
Да, c-строка должна заканчиваться \0. Но если условие цикла задано в виде i<=len_s; то ноль скопируется и так. При этом и к терминальному нулю будет применена функция tolower. Что совершенно не нужно.
Если условие задать i<len_s; то будут скопированы лишь символы строки, без завершающего нуля. Это несколько повысит быстродействие (условно предполагаем, что tolower ресурсоёмка). Тогда нуль добавляем в конец новой строки вручную: ptr = '\0'; Обратите внимание - просто i, не i++. Пост инкремент совершенно ни к чему.