2016-09-23 3 views
1

У меня есть string в main, и я хотел бы передать адрес этой строки функции, которая будет редактировать содержимое этой строки. Я не хочу использовать malloc.C: Как я могу редактировать C-строку в функции без использования malloc

Мой код в настоящее время выглядит следующим образом:

int main(){ 
     char* str = "Hello"; 
     char* para1[] = {"Tea", "Coffee"}; 

     printf("str: %s\n para1: %s\n", str, para1[0]); 

     my_func(str, &para1); 

     printf("str: %s\n para1: %s\n", str, para1[0]); 

     return 1; 
} 

int my_func(char* str, char** para1){ 
     printf("str: %s\n", str); 
     str[0] = 'W'; 
     para1[0] = "Popcorn"; 

     return 1; 
} 

Я не понимаю, как я могу изменить первую букву строки из H в W

Не могли бы вы объяснить, что я делаю неправильно?

+4

1) 'char * str =" Hello ";' -> 'char str [] =" Hello ";' 2) 'my_func (str, & para1);' -> 'my_func (str, para1) ; 'Также перед использованием этой функции у вас должен быть прототип. – BLUEPIXY

+0

@BLUEPIXY В C89 эта функция может быть вызвана без прототипа, и, поскольку, к сожалению, даже современные компиляторы по-прежнему используют режим C89, не может быть предупреждения –

+0

, вы можете определить тип punchard, например 'typedef struct {char data [80]; } punchcard_t' и передать строку в функцию punchcard_t и вернуть ее punchcard_t (длина строки сохраняется, в отличие от передачи по ссылке).В противном случае вам понадобится malloc или реализация malloc локально-статической памяти-пула, поскольку вы не можете вернуть указатель на локальные данные, так как истекает срок его жизни. Это работает, потому что struct действует как обертка над массивом байтов, тем самым сохраняя свою структуру как тип ввода, так и тип возвращаемого значения (тогда как вы не можете «вернуть» char [80]). – Dmitry

ответ

5

Строковые литералы доступны только для чтения. Когда вы определили:

char* string_literal = "Hello"; 

Вы получаете указатель на текст «Привет», который находится в постоянной памяти.

Если вы объявляете это как массив символов:

char string[] = "Hello"; 

Затем вы можете изменить содержимое string с индексом массива обозначения:

string[0] = "W"; 

Теперь вы можете заменить указатель на строку literal с указателем на другой строковый литерал. Например,

string_literal = "New string literal"; 

, потому что здесь, что вы на самом деле делаете переназначение указатель под названием «string_literal», чтобы указать другой адрес в памяти. Сам указатель записывается, но память, на которую она указывает, доступна только для чтения. Вот почему ваше назначение в para1 преуспевает.

2

Строковые литералы являются нередактируемым, так как они, как правило, хранятся в разделе неизменны данных вашего ехе.


Это не о вашей функции, возьмите эту игрушку пример, например:

include <stdio.h> 

int main(void) 
{ 
    char* str = "Hello"; 
    str[0] = 'g'; 
    printf("%s\n", str); 
    return 0; 
} 

Это должно привести к ошибке во время выполнения, я получил:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
Bus error: 10 

Там тонны информации о субъект, таким образом, я больше не буду расширяться.

+0

Я не знаю, кто меня поддержал, но его/ее голос заставил меня добраться до 20 тыс. rep mliestone !!! : D – gsamaras

+1

поздравления !! (*^_ ^) _ ∠ ※ ☆ PAN! – BLUEPIXY

+0

@BLUEPIXY あ り が と う, кто знает, может быть, когда-нибудь я смогу следовать вашему примеру! – gsamaras