2016-11-27 22 views
0
int main() { 
    char src[] = "santosh"; 
    char dest[0]; 
    strncpy(dest, src, 4); 
    printf("%s\n", dest); // expecting o/p "sant" but o/p was "santtosh" 
    int i = 0; 
    while (dest[i]) { 
     printf("%c", dest[i]); //expecting output "sant" but it was "santtosh" 
     i++; 
    } 

    printf("\n"); 
    i = 0; 

    while (src[i]) { 
     printf("%c", src[i]); // expecting o/p "santosh" but it was "anttosh" 
     i++; 
    } 
    return 0; 
} 

У меня возникли проблемы с этим кодом, я запускаю код с помощью gcc-компилятора, и вот вывод, который я получил (раздел комментариев). Почему поведение не соответствует ожиданиям? почему strncpy() способен копировать исходную строку, даже если dest buff недостаточно?Почему strncpy умеет копировать исходную строку, даже если буфер назначения равен нулю?

+5

'символ Dest [0]' <- почти вся ваша программа неопределенное поведение в этой точке. То, что вы говорите с этим объявлением, состоит в том, что массив 'dest' является * фиксированным * размером 0 символов. Поэтому он никогда не может содержать ничего, и любой доступ к нему (чтение * или * запись) не определен. –

+2

Назван в честь британской поп-группы ** UB40 ** ... Вы также должны рассмотреть возможность удаления тега 'C++'. –

+1

Это неопределенное поведение. C позволит вам писать где угодно, и вам решать, нужно ли вам ... – Charles

ответ

1

Ваш код вызывает неопределенное поведение, пытаясь объяснить, почему он производит какой-то вывод, бессмысленно.

Вот проблемы:

  • Вы не включают <stdio.h>, ни <string.h>. Функции вызова, которые ранее не были определены, не в порядке. Включите правильный файл заголовка, чтобы избежать неопределенного поведения.

  • char dest[0]; определяет массив размером 0. К такому объекту нельзя обращаться, даже его адрес не имеет смысла. gcc и clang позволяют это, но в качестве дополнения к стандарту C. Это определение выглядит как опечатка, используйте gcc -Wall -W или clang -Weverything, чтобы включить полезные предупреждения, которые предотвратят такие глупые ошибки.

  • strncpy(dest, src, 4); вызывает неопределенное поведение, так как длина dest составляет менее 4. Обратите внимание, что поведение будет по-прежнему подвержено ошибкам, если dest имеет длину 4, так как strncpy не будет обнулять конечный массив, если длина исходной строки больше или равна аргументу размера. Здесь "santosh" имеет длину 7, поэтому dest будет содержать символы s, a, n и t, но нет нулевого терминатора. Ваш цикл while вызовет неопределенное поведение, поскольку while (dest[i]) получит доступ к dest за его пределами. strncpy() подвержен ошибкам, его семантика широко понята и вызывает ошибки очень легко. Не используйте эту функцию.

  • Как объяснено выше, while (dest[i]) вызывает неопределенное поведение, потому что dest не может быть разыменовываются, как определено в настоящее время, или даже если она была определена как char dest[4];.

Вот улучшенная версия, с помощью snprintf() и strncat():

#include <stdio.h> 
#include <string.h> 

int main(void) { 
    char src[] = "santosh"; 
    char dest[5]; 

    *dest = '\0'; 
    strncat(dest, src, 4); 
    printf("%s\n", dest);  // will output "sant" 
    for (int i = 0; dest[i]; i++) { 
     printf("%c", dest[i]); // will output "sant" too 
    } 
    printf("\n"); 

    snprintf(dest, sizeof dest, "%s", src); 
    printf("%s\n", dest);  // will output "sant" 
    for (int i = 0; dest[i]; i++) { 
     printf("%c", dest[i]); // will output "sant" again 
    } 
    printf("\n"); 

    for (int i = 0; src[i]; i++) { 
     printf("%c", src[i]); // will output "santosh" 
    } 
    printf("\n"); 

    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^