2012-06-19 46 views
7

Tôi đang gọi hàm funcB từ funcA. funcB sử dụng một số câu lệnh printf cho dữ liệu đầu ra. Có cách nào để tôi chụp dữ liệu đó qua số funcA không? Tôi không thể sửa đổi funcB.Làm thế nào để nắm bắt đầu ra của printf?

funcB(){ 
    printf("%s", "My Name is"); 
    printf("%s", "I like ice cream"); 
} 

funcA(){ 
    funcB(); 
} 
+2

Điều gì sẽ xảy ra nếu 'funcB' không in đầu ra của nó, nhưng trả lại nó thành' funcA' thay thế? Khó nói từ mô tả trừu tượng như bạn đã cung cấp, cụ thể hơn. – LihO

+2

* "Đây là câu hỏi C++" * - có vẻ giống như câu hỏi C đối với tôi. Nếu đó là C++ bạn có thể làm một cái gì đó như: [this] (http://stackoverflow.com/a/8076948/168175). – Flexo

+0

Trông giống như một câu hỏi về hệ điều hành cho tôi, như được nói đến trong câu trả lời của tôi. –

Trả lời

10

Câu trả lời này là trung tâm POSIX. Bạn có thể sử dụng freopen để chuyển hướng stdout vào một tệp. Tuy nhiên, bạn sẽ muốn dupSTDOUT_FILENO trước khi thực hiện điều đó, vì vậy bạn có thể khôi phục stdout về điều gì đó tương tự trạng thái ban đầu với fdopen.

int stdout_fd = dup(STDOUT_FILENO); 
freopen(redirected_filename, "w", stdout); 
funcB(); 
fclose(stdout); 
dup2(stdout_fd, STDOUT_FILENO); 
stdout = fdopen(STDOUT_FILENO, "w"); 
close(stdout_fd); 

Đối với luồng C++, bạn có thể sử dụng Johnathan Wakely's answer.

+0

Bạn cai trị dude, nó đã hoạt động! – Gene

0

Đặt funcB vào một chương trình riêng biệt. Sau đó, bạn có thể nắm bắt đầu ra tiêu chuẩn của nó, ví dụ: bằng đường ống hoặc bằng cách chuyển hướng nó đến một tập tin. Làm thế nào để làm điều đó thường phụ thuộc vào hệ điều hành và là bên ngoài lĩnh vực của C + +.

Hoặc, có thể bạn có thể chuyển hướng đầu ra tiêu chuẩn của quy trình funcA 'sang một tệp, sau đó gọi FuncB và truy xuất đầu ra từ tệp.

Một lần nữa, cách thực hiện điều đó nằm ngoài phạm vi C++ và phụ thuộc vào hệ điều hành.

1

Nếu không có gì khác trong chương trình của bạn sử dụng printf, bạn có thể viết phiên bản của riêng mình và liên kết nó một cách rõ ràng. Trình liên kết sẽ không tìm trong thư viện chuẩn nếu hàm đã được định nghĩa. Bạn có thể sử dụng vsprintf để thực hiện, hoặc một số phiên bản an toàn hơn với kiểm tra quá mức nếu nó được cung cấp bởi trình biên dịch của bạn.

1

Nếu bạn sẵn sàng để chơi một trò chơi bẩn xen vào printf bạn có thể 'ăn cắp' sản lượng của nó làm cái gì đó như:

#include <stdio.h> 
#include <stdarg.h> 

static char buffer[1024]; 
static char *next = buffer; 

static void funcB(){ 
    printf("%s", "My Name is"); 
    printf("%s", "I like ice cream"); 
} 

static void funcA(){ 
    funcB(); 
    // Do stuff iwth buffer here 
    fprintf(stderr, "stole: %s\n", buffer); 
    next=buffer; // reset for later. 
} 

int main() { 
    funcA(); 
} 


int printf(const char *fmt, ...) { 
    va_list argp; 
    va_start(argp, fmt); 
    const int ret = vsnprintf(next, sizeof buffer-(next-buffer), fmt, argp); 
    next += ret; 
    va_end(argp); 
    return ret; 
} 

Bạn có thể sử dụng một lá cờ để chỉ ra làm thế nào để xử lý các trường hợp mà bạn muốn printf hoạt động như bình thường. (Ví dụ: ánh xạ nó lên fprintf hoặc sử dụng dlsym()/tương tự để tìm cuộc gọi thực).

Bạn cũng có thể sử dụng realloc để quản lý kích thước bộ đệm hợp lý hơn.

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