Использование всех копий слова с заглавной буквы: почему этот код не работает, когда он выполняет свою функцию?
У меня есть две строки в стиле C:
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
Мне нужно найти начало "быть" с strstr(st, sub_s)
и измените его на заглавные буквы. Новая строка должна быть "" быть или не быть ";
Мне удается сделать это без функции так:
void main()
{
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
char* p;
int i;
while (p = strstr(st, sub_s))
{
for (i = 0; i < strlen(sub_s); i++)
{
p[i] -= 32;
}
}
printf("%s\n", st);
}
Но когда я помещаю этот код в его собственную функцию, он больше не работает:
void main()
{
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
replaceSubstring(st, sub_s);
}
void replaceSubstring(char* str, char* substr)
{
int* p;
int i;
while (p = strstr(str, substr))
{
for (i = 0; i < strlen(substr); i++)
{
p[i] -= 32;
}
}
printf("%s\n", st);
}
Что тут происходит?
1 ответ
В функции, которую вы написали, вы установили тип p
быть int*
не char *
, Это значит когда пишешь
p[i] -= 32;
компилятор примет каждый элемент, на который указывает p
является int
и, следовательно, сделать шаг размера sizeof(int)
в памяти, а не шаг размером 1 в памяти. Другими словами, код интерпретируется как
Start at the location pointed at by p.
Jump forward i * sizeof(int) bytes.
Read an integer value from that location.
Subtract 32 from it.
Write it back
скорее, чем
Start at the location pointed at by p.
Find the character i steps down from there.
Subtract 32 from that character.
Чтобы это исправить, измените тип p
быть char*
не int*
,
Это ошибка, которая может быть легко обнаружена, если вы установите максимальный уровень предупреждения компилятора. Я настоятельно рекомендую делать это, когда вы учитесь кодировать, а затем задавать вопросы о предупреждениях, которые вы получаете, когда вы их не понимаете.
Некоторые другие случайные заметки:
- Тип возврата
main
должно бытьint
неvoid
, - Вместо того, чтобы вычитать 32 из каждого символа, который работает, но не самая ясная вещь в слове, рассмотрите использование
tolower
функция от<ctype.h>
заголовок. - Если искомая подстрока состоит исключительно из буквенных символов (скажем,
":-)"
), то этот код может вызвать бесконечный цикл. Вы понимаете почему? Подумайте, как вы можете это исправить.