Запись в c-строку
-
05-07-2019 - |
Вопрос
мой код поврежден, и я не знаю почему.
1 #include <stdio.h>
2
3 void overwrite(char str[], char x) {
4 int i;
5 for (i = 0; str[i] != '\0'; i++)
6 str[i] = x;
7 }
8
9 int main(void) {
10 char *s = "abcde";
11 char x = 'X';
12 overwrite(s, x);
13 printf("%s\n", s);
14 return 0;
15 }
Отладчик gdb говорит мне, что проблема в строке 6, где я хочу сохранить символ в c-строку (если я использую разыменование указателя lvalue, это та же проблема.) Это то, что он говорит: р>
(gdb) run
Starting program: /tmp/x/x
Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5
5 for (i = 0; str[i] != '\0'; i++)
(gdb) s
6 str[i] = x;
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6
6 str[i] = x;
(gdb) q
Я учусь на книге K & amp; R-C, и это упрощенный пример из главы 2.8 (функция удаления). Я понятия не имею, в чем проблема.
Решение
потому что char * s = " abcde " ;; создает строку в постоянной памяти. попробуйте
char s[] = "abcde";
РЕДАКТИРОВАТЬ: пояснение: char * является указателем, и " abcde " создается в постоянной памяти - > неизменны.
char [] - это массив, который целиком хранится в стеке и инициализируется из памяти, поэтому может изменяться
Другие советы
Когда вы определите указатель на строковый литерал , объявите его как const char *
.
const char *s = "abcde";
Таким образом, ваш компилятор жалуется, когда вы пытаетесь отправить эту строку в функцию overwrite ().
const char *s = "abcde";
char t[] = "fghij";
char x = 'X';
overwrite(s, x); /* oops */
overwrite(t, x); /* ok */
Не спорю, а просто уточню: подумайте, что произойдет, если компилятор это допустит. Вы можете написать:
char *s1="abcde";
char *s2="abcde";
s1[0]='x';
puts(s1);
puts(s2);
Если компилятор распознает, что два литерала одинаковы, и использует их повторно, но затем также разрешает строку 3, вы получите следующий вывод:
xbcde
xbcde
Что, вероятно, не то, что вы хотели бы. Это было бы особенно загадочно, если бы два литерала находились в разных частях программы.
Попробуйте:
#include <iostream>
#include <cstring>
using namespace std;
void overwrite(char[], char);
int main(void)
{
char *s = strdup("abcde");
char X = 'X';
overwrite(s, X);
cout << s << endl;
if(s!=NULL)
delete [] s;
return 0;
}
void overwrite(char str[], char x)
{
for(int i=0; str[i]!='\0'; i++)
str[i] = x;
}
я думаю, это определение параметра, в котором вы определяете тип как массив символов. Пока вы передаете указатель на символ
Вы можете попробовать изменить первую строку следующим образом:
void overwrite(char *str, char x) {
Массив char и указатель char не являются семантически одинаковыми.