2012-08-13 48 views
6

Đối với bất cứ lý do các bản in mã sau (null):scanf động phân bổ

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

int main(void) 
{ 
    char *foo; 
    scanf("%ms", &foo); 
    printf("%s", foo); 
    free(foo); 
} 

Tôi đang cố gắng để cấp phát bộ nhớ cho một chuỗi động nhưng như tôi đã nói trước đó chương trình của tôi chỉ đơn giản là kết quả đầu ra (null). Tôi đã làm việc xung quanh điều này bằng cách tạo một hàm sử dụng getche và realloc nhưng dường như vô nghĩa do thực tế là tôi cũng phải lập trình điều gì sẽ xảy ra nếu người dùng nhập backspace, tab, v.v. Nhưng như tôi đã nói đó chỉ là một công việc xung quanh và tôi thà biết tại sao đoạn code trên không hoạt động ...

Thông tin bổ sung:

tôi đang sử dụng v7.00 Pelles C IDE và biên soạn với C11 chuẩn

+0

'% ms' có ý định làm gì? –

+0

@Greg Cờ m phải tự động cấp phát bộ nhớ để chứa đầu vào. –

+3

Đó có phải là tiêu chuẩn không? Tôi không thấy điều đó trong tài liệu 'scanf' của tôi. –

Trả lời

9

tôi không nhìn thấy %m trong phần 7.21.6.2 của Draft C11 standard (phần trên fscanf). Tôi khuyên bạn nên tránh nó và gọi malloc() như bạn sẽ làm trong C99.

+2

Xem như bạn không thể dự đoán bao nhiêu không gian để phân bổ với 'scanf ("% s ")', tôi cũng khuyên bạn nên tránh 'scanf' hoàn toàn và sử dụng' fgets' và 'sscanf '. – jamesdlin

+4

Ký hiệu'% ms' là một phần mở rộng POSIX trong ['scanf()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/scanf.html) so với phiên bản C chuẩn của ' scanf() '. –

0

% m là một phần mở rộng GNU, có thể là lý do tại sao nó không có sẵn trong Pelles C.

+4

Nó là một phần mở rộng POSIX chứ không chỉ là một phần mở rộng của GNU –

0

Tôi đang sử dụng Linux 3.2.0 amd 64 với gcc 4.7.2. Sử dụng mã:

char *s; 
scanf("%ms", &s); 
printf("%s", s); 
free(s); 

hoạt động tốt nhưng không chấp nhận khoảng trắng.

Đối với phân bổ tĩnh, bạn có thể sử dụng thay vì:

char s[100]; 
printf("Enter string (max 99 characters): "); 
scanf("%100[^\n]s", &s); 
printf("You entered: %s\n", s); 

Hy vọng nó sẽ giúp!

+0

Xin lỗi vì điều đó nhưng bạn không giúp đỡ anh ta vì nếu bạn nhìn vào hàm' scanf() ', bạn chắc chắn sẽ nhận ra rằng nó sai ! nó phải là 'scanf ("% ms ", s)' là s là một con trỏ trong chính nó! se lưu ý rằng không có '&' trước 's'. Bên cạnh đó hãy nhớ rằng nó sẽ không hoạt động cho 'scanf' tiếp theo trong chương trình nếu có bất kỳ !!! Hy vọng nó là rõ ràng !!! –

+3

@Meninx: không, với '% ms', nó phải là' scanf ("% ms", & s) '. Phần mở rộng 'm' POSIX phân bổ chuỗi cho bạn và gán nó cho' s', phải là kiểu 'char *'. –

+1

@RudyVelthuis Bạn nói đúng! Cảm ơn bạn đã chỉ ra điều đó! :) –

0

như Arun nói, giải pháp này là đúng và Meninx 'ý kiến ​​s là sai:

char *s; 
scanf("%ms", &s); 
printf("%s", s); 
free(s); 

Tôi đã đọc các 'người đàn ông scanf', nó nói:

Một tùy chọn '' nhân vật m. Điều này được sử dụng với các chuyển đổi chuỗi (% s,% c,% [),
và giảm người gọi cần phân bổ bộ đệm tương ứng để giữ đầu vào: thay vào đó, scanf() phân bổ bộ đệm đủ kích thước và gán địa chỉ của bộ đệm này cho đối số con trỏ tương ứng, cần là con trỏ đến biến char * (biến này không cần khởi tạo trước cuộc gọi). Người gọi nên sau đó miễn phí (3) bộ đệm này khi không còn cần thiết nữa.

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