2009-07-21 21 views
27

Tôi đang làm việc để nhận một số mã cũ dưới các kiểm tra đơn vị và đôi khi cách duy nhất để cảm nhận hành vi của chương trình hiện có là từ đầu ra của bàn điều khiển.Chuyển hướng cả cout và stdout thành chuỗi trong C++ để kiểm tra đơn vị

Tôi thấy rất nhiều ví dụ trực tuyến về cách chuyển hướng stdout sang tệp khác trong C++, nhưng có cách nào tôi có thể chuyển hướng nó tới luồng trong bộ nhớ để kiểm tra của tôi không phải dựa vào đĩa không?

Tôi muốn nhận bất kỳ thứ gì mà mã kế thừa gửi tới stdout thành chuỗi std :: vì vậy tôi có thể dễ dàng .find trên đầu ra.

Sửa

Mã di sản là xấu như vậy mà nó sử dụng một hỗn hợp của cout << ..printf. Dưới đây là những gì tôi có cho đến nay:

void TestSuite::setUp(void) 
{ 
    oldStdoutBuf = std::cout.rdbuf(); 
    std::cout.rdbuf(consoleOutput.rdbuf()); 
} 
void TestSuite::tearDown(void) 
{ 
    std::cout.rdbuf(oldStdoutBuf); 
} 

Vấn đề là điều này không không đầu ra chụp sử dụng printf. Tôi muốn thứ gì đó có cả hai. Bất kỳ ý tưởng?

+0

Không có câu trả lời nào dưới đây có hiệu quả đối với tôi, bạn có ví dụ làm việc cho điều này không? – rraallvv

Trả lời

14

std::stringstream có thể là những gì bạn đang tìm kiếm.

CẬP NHẬT
Được rồi, đây là một chút hack, nhưng có lẽ bạn có thể làm điều này để lấy kết quả printf:

char huge_string_buf[MASSIVE_SIZE]; 
freopen("NUL", "a", stdout); 
setbuf(stdout, huge_string_buffer); 

Lưu ý bạn nên sử dụng "/ dev/null" cho Linux thay vì của "NUL". Điều đó sẽ nhanh chóng bắt đầu để điền vào huge_string_buffer. Nếu bạn muốn có thể tiếp tục chuyển hướng đầu ra sau khi bộ đệm đầy, bạn sẽ phải gọi fflush(), nếu không nó sẽ ném một lỗi. Xem std::setbuf để biết thêm thông tin.

+0

Chấp nhận câu trả lời của bạn như stringstream là con trỏ tốt và UPDATE của bạn là về như xa như chúng tôi có thể sẽ nhận được mà không cần viết một số lộn xộn cực kỳ phức tạp, bây giờ tôi nghĩ rằng tôi sẽ chỉ viết vào một tập tin và hy vọng tôi sẽ không cần printf đầu ra cho nhiều thử nghiệm. – thelsdj

+3

Hoạt động tốt, nhưng nếu tôi sử dụng nhiều bài kiểm tra đơn vị, một số lỗi với một ngoại lệ vì bộ đệm đã được giải phóng và stdout được ghi vào đó. Trong trường hợp chỉ chuyển hướng tạm thời vào bộ đệm, hãy sử dụng 'setbuf (stdout, NULL);' ở cuối quá trình sử dụng. – Martze

+0

Xem câu trả lời này để tránh hệ thống "NUL" -Hack on POSIX: http://stackoverflow.com/a/19499003/1557062 – sigy

2

Bạn có thể sử dụng freopen(..., stdout) và sau đó đổ tệp vào bộ nhớ hoặc std::string.

+0

Tôi thực sự muốn bỏ qua việc phải sử dụng hệ thống tệp. Một cái gì đó mà chỉ sử dụng ram sẽ là tốt nhất. – thelsdj

+0

Vào thời điểm đó, bạn phải nhấn vào hệ điều hành. – MSN

2

Đây có thể là một sự thay thế:

char bigOutBuf[8192]; 
char savBuf[8192]; 

fflush(stdout); 
setvbuf(stdout,bigOutBuf,IOFBF,8192);//stdout uses your buffer 

//after each operation 
strncpy(savBuf,bigOutBuf,8192);//won't flush until full or fflush called 

//... 

//at long last finished 
setbuf(stdout,NULL);//reset to unnamed buffer 

này chỉ chặn đầu ra đệm, vì vậy vẫn còn đi để an ủi hoặc bất cứ nơi nào.

Hy vọng điều này sẽ hữu ích.

+1

IOFBF của _IOFBF?Tôi đã phải sử dụng sau này để có được điều này làm việc – Gayan

+0

Tôi muốn tắt hoàn toàn giao diện điều khiển, giữ chỉ là bộ đệm bị bắt là nó có thể? – rraallvv

-4

Thử chạy nước rút, hiệu quả hơn.

int i; 
char str[] = "asdf"; 
char output[256]; 
sprintf(output, "asdfasdf %s %d\n", str, i); 
Các vấn đề liên quan