2010-08-13 31 views
10
print2fp(const void *buffer, size_t size, FILE *stream) { 

if(fwrite(buffer, 1, size, stream) != size) 
    return -1; 

return 0; 
} 

Làm cách nào để ghi dữ liệu vào luồng chuỗi thay vì luồng Tệp?Chuỗi luồng trong C

+0

Tương tự như câu hỏi trước đây của tôi: http://stackoverflow.com/questions/1741191/creating-a-file-stream-that-results-in-a-string – Edmund

+0

Vì bạn không có các chức năng chuỗi chuỗi POSIX 2008, có thể bạn không may mắn - trừ khi bạn có thể tìm thấy một thư viện mô phỏng chúng đủ tốt cho các mục đích của bạn. –

+1

** Luồng chuỗi **
http://www.gnu.org/s/libc/manual/html_node/String-Streams.html –

Trả lời

2

chỉ cần sử dụng sprintf http://www.cplusplus.com/reference/cstdio/sprintf/

ví dụ từ refference:

#include <stdio.h> 

int main() 
{ 
    char buffer [50]; 
    int n, a=5, b=3; 
    n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); 
    printf ("[%s] is a string %d chars long\n",buffer,n); 
    return 0; 
} 

Output:

[5 cộng với 3 8] là một chuỗi dài 13 ký tự

Cập nhật: Dựa trên các đề xuất trong nhận xét: Sử dụng snprinft vì nó an toàn hơn (ngăn chặn các cuộc tấn công tràn bộ đệm) và di động.

#include <stdio.h> 

int main() 
{ 
    int sizeOfBuffer = 50; 
    char buffer [sizeOfBuffer]; 
    int n, a=5, b=3; 
    n= snprintf (buffer, sizeOfBuffer, "%d plus %d is %d", a, b, a+b); 
    printf ("[%s] is a string %d chars long\n",buffer,n); 
    return 0; 
} 

ý rằng snprintf giây tranh luận thực sự là tối đa kích thước cho phép để sử dụng, vì vậy bạn có thể đặt nó vào một giá trị thấp hơn sizeOfBuffer, tuy nhiên đối với trường hợp của bạn nó sẽ là không cần thiết. Snprintf chỉ viết SizeOfBuffer -1 ký tự và sử dụng byte cuối cùng cho ký tự chấm dứt.

Và chỉ để piss off tất cả mọi người từ các bộ phận embbed và an ninh, đây là một liên kết đến http://www.cplusplus.com/reference/cstdio/snprintf/

+2

Không sử dụng sprintf(), hầu như mọi lần sử dụng sprintf() sẽ phát nổ thỉnh thoảng. Sử dụng asprintf() thay vào đó, nó sẽ malloc một bộ đệm của chiều dài cần thiết cho bạn. – cmaster

+3

Hoặc 'snprintf' trong mã di động. Ngoài ra, xin vui lòng không liên kết với cplusplus.com, trang web đó có đầy đủ các lỗi. cppreference.com là tốt hơn. –

+0

Ngoài ra, sprintf và vsprintf có mối quan ngại về bảo mật. http://www.codecogs.com/library/computing/c/stdio.h/printf.php?alias=snprintf ** "** Chức năng sprintf và vsprintf dễ dàng bị lạm dụng theo cách thức cho phép người dùng độc hại tùy tiện Bởi vì sprintf và vsprintf giả định một chuỗi dài vô hạn, người gọi phải cẩn thận không làm tràn không gian thực tế, điều này thường rất khó để đảm bảo.Để an toàn, các lập trình viên nên sử dụng giao diện snprintf thay thế. ** "** – mike

9

Có một chức năng rất gọn gàng trong tiêu chuẩn POSIX 2008: open_memstream(). Bạn sử dụng nó như thế này:

char* buffer = NULL; 
size_t bufferSize = 0; 
FILE* myStream = open_memstream(&buffer, &bufferSize); 

fprintf(myStream, "You can output anything to myStream, just as you can with stdout.\n"); 
myComplexPrintFunction(myStream); //Append something of completely unknown size. 

fclose(myStream); //This will set buffer and bufferSize. 
printf("I can do anything with the resulting string now. It is: \"%s\"\n", buffer); 
free(buffer); 
+1

Có cách nào khác thay thế cho 'open_memstream'? Một số nền tảng (solaris trong số đó) không cung cấp này [chưa]. –

+0

@BrianVandenberg Gần nhất sẽ là 'asprintf()', cũng không được cung cấp bởi tất cả các nền tảng. Tất cả các lựa chọn thay thế khác có vấn đề bảo mật nghiêm trọng vì chúng có thể tràn bộ đệm được cung cấp ('sprintf()' và 'fmemopen()'), hoặc buộc bạn phải chạy chuỗi hai lần để tránh thất bại khi bộ đệm preallocated của bạn quá nhỏ (' snprintf() '). Chỉ 'asprintf()' và 'open_memstream()' cung cấp các ngữ nghĩa truyền đơn lẻ an toàn. Tuy nhiên, nếu 'asprintf()' sẽ làm việc cho bạn, bạn có thể dễ dàng thực hiện phiên bản của riêng bạn thông qua hai đường dẫn của 'vsprintf()'. – cmaster

+0

Cảm ơn bạn đã phản hồi. Tôi đang chuyển một thư viện Tôi không phải là người bảo trì cho Solaris sử dụng 'open_memstream' một số tiền hợp lý và tôi đã hy vọng tìm cách cung cấp một phiên bản tùy chỉnh để tránh thay đổi mã của họ. Tôi có thể phải sử dụng interposition thư viện với một tùy chỉnh 'write()/close()' (gọi các phiên bản libc của khóa học). –