2008-11-06 32 views
11

Tôi có bộ đệm mảng char mà tôi đang sử dụng để lưu trữ các ký tự mà người dùng sẽ nhập từng cái một. Mã của tôi bên dưới công trình nhưng có một vài trục trặc mà tôi không thể hình dung ra:mảng chuỗi với ký tự rác ở cuối

  1. khi tôi thực hiện một printf để xem những gì trong bộ đệm, nó lấp đầy nhưng tôi nhận được các ký tự rác ở cuối
  2. nó sẽ không dừng lại ở 8 ký tự mặc dù được khai báo là char Buffer [8];

Ai đó có thể giải thích cho tôi điều gì đang xảy ra và có lẽ cách tôi có thể khắc phục vấn đề này? Cảm ơn.

char Buffer[8]; //holds the byte stream 
int i=0; 

if (/* user input event has occurred */) 
{ 
     Buffer[i] = charInput; 
     i++; 

     // Display a response to input 
     printf("Buffer is %s!\n", Buffer); 

} 

Output:

 
tagBuffer is 1┬┬w! 
tagBuffer is 12┬w! 
tagBuffer is 123w! 
tagBuffer is 1234! 
tagBuffer is 12345! 
tagBuffer is 123456=! 
tagBuffer is 1234567! 
tagBuffer is 12345678!

tagBuffer là 123456789!

Trả lời

26

Bạn phải kết thúc chuỗi bằng ký tự \ 0. Đó là lý do tại sao chúng được gọi là không có chuỗi bị chấm dứt.

Bạn cũng nên phân bổ thêm 1 char để giữ \ 0.

+0

Tuyệt vời. Cảm ơn. Chỉ một câu hỏi là: điểm đệm [8] là gì? – Steve

+0

buffer [8] báo cho trình biên dịch đặt 8 byte bộ nhớ cho mảng của bạn. Chuỗi của bạn có thể ngắn hơn (bằng cách làm "bộ đệm [4] = 0;" ví dụ) nhưng không thể (hoặc không nên) dài hơn. –

+1

Bộ đệm [8] là bộ đệm cho 7 ký tự và một terminator ;-). –

8

Điều duy nhất bạn chuyển đến hàm printf() là một con trỏ đến ký tự đầu tiên của chuỗi. printf() không có cách nào để biết kích thước mảng của bạn. (Nó thậm chí không biết nếu nó là một mảng thực tế, vì một con trỏ chỉ là một địa chỉ bộ nhớ.)

printf() và tất cả các hàm chuỗi c tiêu chuẩn giả định rằng có 0 ở cuối chuỗi của bạn. printf() ví dụ sẽ tiếp tục in các ký tự trong bộ nhớ, bắt đầu từ các char mà bạn vượt qua đến chức năng, cho đến khi nó chạm một 0.

Vì vậy, bạn nên thay đổi mã của bạn để một cái gì đó như thế này:

char Buffer[9]; //holds the byte stream 
int i=0; 

if(//user input event has occured) 
{ 
     Buffer[i] = charInput; 
     i++; 

     Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result. 

     // Display a response to input 
     printf("Buffer is %s!\n", Buffer); 

} 
0

Nếu bạn đang lập trình bằng C hoặc C++, bạn phải nhớ rằng: 1) các chuỗi được kết thúc bằng ký tự \ 0. 2) C không có kiểm tra ranh giới tại các chuỗi, chúng chỉ là mảng ký tự.

-1

Bạn cũng có thể muốn xem xét sử dụng stringstream.

+1

stringstream không phải là C liên quan. – quinmars

3

Ngoài các nhận xét trước về việc chấm dứt bằng không, bạn cũng phải chấp nhận trách nhiệm vì không làm tràn bộ đệm của riêng bạn. Nó không dừng lại ở 8 ký tự vì mã của bạn không dừng lại! Bạn cần một cái gì đó như sau (heo con-ủng hộ vào đề nghị của Jeremy):

#define DATA_LENGTH 8 
#define BUFFER_LENGTH (DATA_LENGTH + 1) 

char Buffer[BUFFER_LENGTH]; //holds the byte stream 
int charPos=0; //index to next character position to fill 

while (charPos <= DATA_LENGTH ) { //user input event has occured 
    Buffer[i] = charInput; 

    Buffer[i+1] = '\0'; 

    // Display a response to input 
    printf("Buffer is %s!\n", Buffer); 

    i++; 

} 

Nói cách khác, hãy chắc chắn để ngừng nhận dữ liệu khi độ dài tối đa đã đạt tới, bất kể những gì môi trường cố gắng đẩy vào bạn .

+0

Sử dụng sizeof (Bộ đệm)! –

+0

@ Jonathan: Tôi giả định rằng DATA_LENGTH là khái niệm miền ứng dụng chính và kích thước của Bộ đệm là giá trị phụ thuộc, chứ không phải ngược lại. Có thể có các cách sử dụng khác của DATA_LENGTH không liên quan gì đến Bộ đệm và do đó không nên đề cập đến nó. –

+0

@ joel.neely mặc dù mã của bạn ở trên là không chính xác (trong khi tuyên bố bình luận ra khỏi vị trí), bạn xứng đáng một upvote vì thiết lập các ký tự tiếp theo để '\ 0' LÀ GIẢI PHÁP. tôi khuyên bạn nên chỉnh sửa "Bộ đệm [i] = charInput; Bộ đệm [i + 1] = '\ 0'; i ++;" cho rõ ràng, mặc dù thực hiện của bạn không chính xác, chỉ khó khăn hơn để gỡ lỗi bởi vì bạn đặt 2 biến trong cùng một dòng (câu hỏi về phong cách, tôi đoán). –

0

Đó là kỳ lạ mà không ai có đề cập đến khả năng này:

char Buffer[8]; //holds the byte stream 
int i = 0; 

while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF) 
{ 
    Buffer[i] = charInput; 
    i++; 

    // Display a response to input 
    printf("Buffer is %.*s!\n", i, Buffer); 
} 

ký hiệu trong chuỗi định dạng printf() này quy định độ dài tối đa của chuỗi sẽ được hiển thị, và không yêu cầu chấm dứt null (mặc dù null chấm dứt cuối cùng là cách tốt nhất để đi - ít nhất một khi bạn rời khỏi vòng lặp này).

Vòng lặp while là đáng tin cậy hơn một đơn giản if, và phiên bản này đảm bảo rằng bạn không tràn cuối của bộ đệm (nhưng không đảm bảo bạn lại đủ không gian cho một trailing NUL '\0'. Nếu bạn muốn xử lý mà , sử dụng sizeof(Buffer) - 1 và sau đó thêm NUL sau vòng lặp.

0

Kể từ Buffer không được khởi tạo, nó bắt đầu với tất cả các giá trị 9 rác. Từ đầu ra quan sát, 2, 3, 4, 5, 6, 7, 8 và 2 phần tử vị trí bộ nhớ kế tiếp (bên ngoài mảng) ngay lập tức rõ ràng là 'T', 'T', 'W', '\0', '\0', '=', '\0', '\0', '\0'.

Chuỗi tiêu thụ tất cả ký tự cho đến khi thấy ký tự NULL. Đó là lý do tại sao, trong mỗi lần lặp lại, vì các phần tử mảng được gán từng cái một, bộ đệm được in lên đến phần nơi có một bộ đệm NULL.

Tức là, chuỗi có hành vi không xác định nếu mảng ký tự không kết thúc bằng '\0'. Bạn có thể tránh điều này bằng cách có thêm khoảng trống cho '\0' ở cuối bộ đệm.

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