2016-08-26 10 views
-1

у меня есть вопрос, я знаю следующая реализация работает правильно:C Программирование, изменение строкового значения в функции без прохождения размера в качестве параметра

void editMessage(char* message , int sizeOfMessage){ 
    char newMessage[] = "modified"; 

    printf("size of message is %lu \n",sizeof(message)); 
    printf("size of new message is %lu \n",sizeof(newMessage)); 

    if (sizeof(newMessage) <= sizeOfMessage) { 

     for (int i=0 ; i < sizeof(newMessage); i++) { 

      message[i] = newMessage[i]; 

     } 

    } else { 
     printf("size of new message is too big\n"); 
    } 

} 

int main() { 

    char randMessage[] = "original message"; 
    editMessage(randMessage,sizeof(randMessage)); 
    printf("the value of randMessage after function call is %s \n",randMessage); 
    return 0; 
} 

, но если я хочу, чтобы изменить значение строки в функции без прохождения размер указателя, возможно ли это? если да, то как? если нет, почему бы и нет?

я имею в виду я ищу, чтобы изменить выше editMessage Функция что-то вроде этого:

void editMessage(char* message){ 
    char newMessage[] = "modified"; 

    printf("size of message is %lu \n",sizeof(message)); 
    printf("size of new message is %lu \n",sizeof(newMessage)); 

    if (sizeof(newMessage) <= sizeOf(message)) { 

     for (int i=0 ; i < sizeOf(message); i++) { 

      message[i] = newMessage[i]; 

     } 

    } else { 
     printf("size of new message is too big\n"); 
    } 

} 

и вызова в основной, как этот

editMessage(randMessage); 

, почему это не работает, может один, пожалуйста, объясните в деталях, и тогда я бы принял его ответ? Спасибо!

+5

'sizeof (message)' - * размер указателя *, а не размер объекта, на который он указывает. – EOF

+1

Используйте 'strlen', чтобы получить длину * строки. –

+1

@ user3001566 По крайней мере, первая функция, которую вы показали, неверна и не имеет смысла. :) –

ответ

3

sizeOf(message) не будет работать. sizeOf(message) придаст размер переменной message, а так как первоначально message - указатель, вы получите размер указателя.


Поскольку это NUL завершается строкой, вы можете получить длину строки, используя strlen() и использовать это в вашей функции.


Таким образом, ваш код должен выглядеть примерно так,

void editMessage(char* message){ 
    char newMessage[] = "modified"; 
    int size = strlen(message); 

    printf("size of message is %d \n", size); 
    printf("size of new message is %lu \n",sizeof(newMessage)); 

    if (sizeof(newMessage) <= size) { 

     for (int i=0 ; i < size; i++) { 

      message[i] = newMessage[i]; 

     } 

    } else { 
     printf("size of new message is too big\n"); 
    } 

} 

Для массива char, не завершенного NUL, нет никакого способа узнать длину другой, то посылая длину массива char в качестве параметра.

Поэтому в функции вызова вам необходимо отслеживать количество char s, которое вы пишете в массиве (чтобы узнать длину).

Обратите внимание, я не говорю строку, поскольку массив char становится строка только тогда, когда она прекращается по NUL характер.


Примечание:

Используйте стандартное определение main()

int main(void) //if no command line arguments. 
+0

Что делать, если массив символов не будет прерван нулем? то если я не могу использовать strlen, то какое решение? если бы вы могли объяснить это условие и добавить его в свой ответ, тогда я бы принял ваше сообщение как ответ этой темы, спасибо – Jack

+0

@ user3001566, там вы идете .. :) – Haris

+0

Большое спасибо! – Jack

1

В C

void func(char message[]) становится void func(char *message). Итак, когда вы вызываете sizeof(message) в вызываемой функции, он будет возвращать только размер указателя. В массиве «C» значения не передаются.

Если вы уверены, ваш массив символов всегда будет иметь нулевое завершение, вы используете strlen, чтобы получить его длину.

+0

Что делать, если массив charachter не будет завершен нулем? то если я не могу использовать strlen, то какое решение? благодаря – Jack

0

Используйте strlen, чтобы получить длину входной строки.

КСТАТИ: Обратите внимание на эту часть кода:

if (sizeof(newMessage) <= sizeOfMessage) { 

    for (int i=0 ; i < sizeOfMessage; i++) { 

     message[i] = newMessage[i]; 

sizeof(newMessage) Если 9 sizeOfMessage 100 вы получите доступ к newMessage[9]newMessage[99], который находится за пределами массива.

2

если я хочу изменить значение строки в функции без передачи указателя, возможно ли это? если да, то как? если нет, почему бы и нет?

Вы можете определить длину входного сообщения через функцию strlen(). Предположим, что вы указали, что функция работает так, как предполагалось, только для правильных строк с нулевым завершением, поэтому разумно предположить, что массив, содержащий строку, достаточно длинный для его размещения, включая терминатор. Таким образом, в какой-то степени вы могли бы strlen(message) + 1 вместо оригинала sizeOfMessage.

Однако, то есть более, чем ограничение исходной функции, так как массив, содержащий строку может быть больше, чем строка требуется. Если вы используете длину входной строки для ограничения длины строки замены, вы никогда не сможете использовать такую ​​избыточную емкость. Рассмотрим:

int main() { 
    char randMessage[1024] = ""; 
    /* 
     * sizeof(randMessage) is 1024, but strlen(randMessage) is 0. Which do 
     * you prefer as the limit on the size of the message that editMessage() 
     * can insert? 
     */ 
    editMessage(randMessage, sizeof(randMessage)); 
    return 0; 
}