#c #pointers #concatenation
#c #указатели #объединение
Вопрос:
Я выполняю некоторые упражнения и пытаюсь объединить две строки, используя только указатели (без массивов символов). Кажется, что мой код компилируется (примечание: я использую старый 16-разрядный компилятор Open Watcom):
#include <stdio.h>
int main(){
char *str1 = "first";
char *str2 =" second";
strcat2(str1,str2);
for(;*str1!='';str1 ){
printf(str1);
}
return 0;
}
int strcat2(char *s,char *t){
for(;*s!='';s ){
;
}
while((*s = *t )!=''){
;
}
*t ;
t='';
return 0;
}
Когда я попытался запустить его, ничего не произошло.
Я уверен, что моя вышеупомянутая работа ужасно ошибочна. Мы будем признательны за любые советы и помощь.
Комментарии:
1. подсказка: где находится пространство для объединения?
Ответ №1:
str1
и str2
, которые вы объявили, являются строковыми литералами, которые не могут быть изменены. В исполняемых файлах Linux содержимое адреса, на который указывает str1
и str2
, хранится в .rodata
разделе исполняемого файла, который недоступен для записи. В других исполняемых файлах содержимое хранится в аналогичном месте, которое недоступно для записи. Для выполнения этой работы вы должны использовать массив или динамически выделяемую область памяти. Убедитесь, что при объединении строки, в которую вы вставляете, в другой строке достаточно места для их размещения.
ПРАВКА1:
Либо сделайте
char str1[BUFF_SIZ] = "Hello", str2[BUFF_SIZ] = " Man";
/* Now do strcat */
/* The strlen (str1) strlen (str2) should be lessthan BUFF_SIZ */
или
char *str1, *str2;
str1 = malloc (sizeof (char) * BUFF_SIZ);
str2 = malloc (sizeof (char) * BUFF_SIZ);
strcpy (str1, "Hello");
strcpy (str2, " Man");
/* Now do strcat */
/* The strlen (str1) strlen (str2) should be lessthan BUFF_SIZ */
Комментарии:
1. Вопрос от K amp; R. И в нем конкретно говорится о необходимости объединения строк с использованием указателей.
2. @JJG: Проверьте правку, посмотрите, отвечает ли это на ваш вопрос. То, что вы реализовали, — это использование указателя, но, к сожалению, содержимое адреса указателя не может быть записано в соответствии со стандартами, строковые литералы не могут быть записаны. При использовании динамического выделения памяти память обычно выделяется из кучи, и вы можете ее изменить. Для массива также он хранится внутри стека, в общем случае, который вы можете записать.
3. Сейчас я перевариваю ваш ответ. Кажется, нет способа выполнить strcat для произвольных str1 и str2. Мы должны заранее знать их размер, верно?
4. посмотрите, если две строки имеют длину
n
каждая, тогда объединение будет максимально,2n
поэтому вы должны сохранить предоставление2n
размера.5. не следует ли вам скопировать
"Man"
строку вstr2
и также выделить дляstr2
памяти?
Ответ №2:
Ваш код не будет работать. Если быть педантичным, это вызывает неопределенное поведение, потому что вы пытаетесь изменить содержимое строкового литерала.
char *str1 = "first";
char *str2 =" second";
str1
указывает на «first», который находится в постоянной ячейке памяти.
Вместо указателя на строковый литерал у вас должен быть массив символов достаточной емкости для хранения объединенной строки "firstsecond"
Это работает в соответствии с ожиданиями
#include <stdio.h>
int strcat2(char *s,char *t){
for(;*s!='';s ){
}
while((*s = *t )!=''){
}
t='';
return 0;
}
int main(){
char str1[15] = "first";
char *str2 =" second";
strcat2(str1,str2);
printf("%s",str1);
return 0;
}
Онлайн-демонстрация здесь
Комментарии:
1. Вопрос взят из знаменитого справочника K amp; R. В упражнении говорится: «Напишите версию функции strcat с указателем … …strcat(s,t) копирует строку t в конец s». Если мой метод изначально ошибочен, как мне это сделать?
2. Спасибо за вашу помощь. У меня есть небольшая оговорка в том, что str1 является предопределенным массивом символов. Такое ощущение, что это противоречит духу вопроса при использовании указателей.
Ответ №3:
цитата из man:strcat:
char * strcat ( char * destination, const char * source );
...
Parameters
destination
Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
Ваша строка назначения не достаточно большая.
Ответ №4:
Вам нужен доступный для записи и достаточно большой буфер для записи, например
char str1[32] = "first";