2016-02-20 25 views
8

Tôi muốn chuyển các phần tử từ chuỗi này sang chuỗi khác và do đó đã viết chương trình sau. Ban đầu, tôi nghĩ rằng vòng lặp for nên thực hiện cho đến khi ký tự NULL (bao gồm cả nó tức là) đã được sao chép. Nhưng trong mã này, vòng lặp for kết thúc nếu một ký tự NULL đã được tìm thấy (nghĩa là, chưa được sao chép), nhưng nó vẫn có thể hiển thị chuỗi trong đó các phần tử đã được sao chép. Làm thế nào là điều này có thể, nếu không có nhân vật NULL ở nơi đầu tiên?Sao chép các phần tử từ một mảng ký tự sang một dải ký tự khác

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    char temp[100], str[100]; 
    fgets(str, 100, stdin); 
    int i; 
    for(i = 0; str[i]!='\0'; i++) 
    { 
     temp[i] = str[i]; 
    } 
    puts(temp); 
    return 0; 
} 
+3

'NULL' là macro có hằng số _null pointer_. Điều này không liên quan ở đây. Bạn có nghĩa là ký tự 'NUL' hoặc' nul' ASCII với giá trị số nguyên '0'. – Olaf

+0

Đọc về 'strcpy'. –

+1

@Pete Becker Tôi nghĩ rằng điều này rất có thể giống như bài tập về nhà/hướng dẫn (* nghĩa là * dự định/được thiết kế để làm cho ** nhận thức ** về các vấn đề với chuỗi sao chép). Đơn giản chỉ cần nói với ai đó để đọc về 'strcpy' không giúp mang lại sự hiểu biết đó. – Tersosauros

Trả lời

7

Chức năng void puts(const char *) dựa vào size_t strlen(const char *) và đầu ra của chức năng này là undefined khi không có terminator null trong lập luận thông qua (xem this answer). Vì vậy, trong trường hợp của bạn, strlen bên trong puts có thể tìm thấy giá trị 0 'bên cạnh' mảng của bạn trong bộ nhớ dẫn đến hành vi thích hợp của puts, tuy nhiên không cần phải luôn luôn như vậy vì nó không được xác định.

3

Khi bạn khai báo char temp[100] mà không khởi tạo nó vào bất cứ thứ gì, nó chỉ mất bộ nhớ chưa được khởi tạo. Bộ nhớ này có thể là bất cứ thứ gì. Ví dụ, chương trình sau đây sẽ viết ra những nội dung ban đầu về điều đó, như số nguyên:

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    char temp[100]; 
    int i; 
    for(i = 0; i < 100 ; i++) 
    { 
     fprintf(stdout, "%d ", temp[i]); 
    } 
    return 0; 
} 

in này ra luôn khác nhau đối với tôi, mặc dù một số người may mắn nó giữ phần in số không. ví dụ:

88 -70 43 81 -1 127 0 0 88 -70 43 81 -1 127 0 0 1 0 0 0 0 0 0 0 112 -70 43 81 -1 127 0 0 0 64 -108 14 1 0 0 0 72 50 -13 110 -1 127 0 0 -128 -70 43 81 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -70 43 81

88 90 72 88 -1 127 0 0 88 90 72 88 -1 127 0 0 1 0 0 0 0 0 0 0 112 90 72 88 -1 127 0 0 0 -96 119 7 1 0 0 0 72 18 72 105 -1 127 0 0 -128 90 72 88 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 90 72 88

88 -6 -79 87 -1 127 0 0 88 -6 -79 87 -1 127 0 0 1 0 0 0 0 0 0 0 112 -6 -79 87 -1 127 0 0 0 0 14 8 1 0 0 0 72 34 57 104 -1 127 0 0 -128 -6 -79 87 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -6 -79 87

gì rất có thể xảy ra là chuỗi không null-terminated của bạn đang được vô tình null-chấm dứt nhờ thực tế là temp[strlen(str)] là , bởi một fluke, \0.

+1

in các biến đó là hành vi không xác định –

+0

@Giorgi Làm thế nào? AFAIK, nó được định nghĩa là tôi nhận được 100 byte, nhưng giá trị của những byte đó là không xác định. Họ nên được an toàn để in, nhưng nó không bao giờ được đảm bảo những gì họ đang có. – yaakov

+2

Không, vui lòng đọc về khái niệm hành vi không xác định. Đọc các biến chưa được khởi tạo là UB. –

7

Dưới đây là các đầu vào và đầu ra trên máy tính của tôi:

0 
0 
絯忐` 

Process returned 0 (0x0) execution time : 1.863 s 
Press any key to continue. 

Xem rác "絯 忐`"? Đây là hành vi không xác định. Chương trình của bạn hoạt động tốt vì bạn là (un) may mắn.

Một lần nữa, hành vi không xác định không xứng đáng với số nhiều cuộc thảo luận.

+3

Tôi sẽ +1, cho đến khi tôi đọc dòng cuối cùng: ** "** _ hành vi không xác định không xứng đáng một cuộc thảo luận ._ **" ** Trong khi đúng là OP là "(un) may mắn" như bạn đặt nó, tôi nghĩ rằng không thảo luận rằng ** hành vi undefined ** là * không trả lời câu hỏi đúng *. – Tersosauros

+1

Mọi thứ và mọi thứ đều có thể xảy ra khi các hành vi không xác định diễn ra. Như K & R đã chỉ ra một cách khôn ngoan, "nếu bạn không biết làm thế nào chúng được thực hiện trên các máy khác nhau, sự ngây thơ đó có thể giúp bảo vệ bạn." Vì vậy, tôi nghĩ tốt hơn là không thảo luận về các hành vi không xác định. –

Các vấn đề liên quan