获取 C/C++ 中打印的最后一个字符串
Get the last string printed in C/C++
我正在尝试使用 googletest 创建一个测试器。问题是我正在测试的函数返回 void 并打印结果。我想将最后一个字符串打印到控制台中,以便我可以测试输出。该字符串可能包括 \n
.
所以我有函数本身:
void f_sequence(char sequenceStr[])
{
//logic...
if(condotion1)
printf("somthing1");
else if(condotion2)
printf("somthing2")
(...)
}
然后是测试人员:
TEST(TesterGroup, TesterName)
{
f_sequence("input");
EXPECT_EQ("somthing1", /*how do i get the output?*/);
}
可能吗?
我测试的函数是用 c 编写的,而测试函数本身(测试器)是用 c++ 编写的。使用 printf
打印输出。我无法更改功能本身。我正在使用 CLion 最新版本。
我不知道是否有可能获得最后打印的内容,但是如果您在调用测试函数之前控制环境,您可以重定向标准输出的位置,它允许您将其写入一个文件,然后您可以检查它。
请参阅 this old answer 哪个 IMO 被忽略了。它的例子在这里修改:
FILE *fp_old = stdout; // preserve the original stdout
stdout = fopen("/path/to/file/you/want.txt","w"); // redirect stdout to anywhere you can open
// CALL YOUR FUNCTION UNDER TEST HERE
fclose(stdout); // Close the file with the output contents
stdout=fp_old; // restore stdout to normal
// Re-open the file from above, and read it to make sure it contains what you expect.
两种方式:
如果您使用的是 POSIX 兼容系统,您可以使用 >
将程序的输出重定向到一个文件,然后稍后从文件中读取以确认输出是正确的.
另一种方式是这样的:
freopen("output.txt", "w", stdout);
f_sequence();
freopen("/dev/tty", "w", stdout);
用于 POSIX 兼容系统。在其他平台上,您需要将 "/dev/tty"
更改为其他内容。我不知道执行此操作的完全便携方式。
然后阅读output.txt
。上面的代码片段所做的是改变 stdout
是什么,以便它打印到一个文件而不是普通的标准输出。
一个解决方案:您可以编写一个单独的程序来执行该功能,并且在单元测试中,您可以将该程序作为子进程执行并检查输出。这可以用 std::system
来完成,但要非常小心,不要将任何非常量输入传递给它。即使在单元测试中,您也不希望 shell 注入漏洞。存在避免在子进程中使用 shell 的系统特定函数。
另一种解决方案,至少在 POSIX 上可行:用文件描述符替换标准输出/错误流,然后读取文件。
Googletest 特定:似乎有 testing::internal::CaptureStdout
,它似乎实现了替换标准流的想法。但正如命名空间所暗示的那样,这不是官方的 API,因此将来可能会更改。
C
中有一个 API 调用 ( cmd_rsp
) with source code here 的解决方案,当在您的程序中调用时,会创建一个单独的进程,并通过管道连接到 stdin
和 stdout
,它通过自动调整大小的缓冲区从中接受命令和 returns 响应。在概念上类似于 popen(...)
。
一个简单的用例:
char *buf = NULL;
/// test cmd_rsp
buf = calloc(BUF_SIZE, 1);
if(!buf)return 0;
if (!cmd_rsp("dir /s", &buf, BUF_SIZE))//note the first argument can be any legal command that
//can be sent via the CMD prompt in windows,
//including a custom executable
{
printf("%s", buf);
}
else
{
printf("failed to send command.\n");
}
free(buf);
将标准输出重定向到缓冲区。
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int stdoutSave;
char outputBuffer[BUFFER_SIZE];
void replaceStdout()
{
fflush(stdout); //clean everything first
stdoutSave = dup(STDOUT_FILENO); //save the stdout state
freopen("NUL", "a", stdout); //redirect stdout to null pointer
setvbuf(stdout, outputBuffer, _IOFBF, 1024); //set buffer to stdout
}
void restoreStdout()
{
freopen("NUL", "a", stdout); //redirect stdout to null again
dup2(stdoutSave, STDOUT_FILENO); //restore the previous state of stdout
setvbuf(stdout, NULL, _IONBF, BUFFER_SIZE); //disable buffer to print to screen instantly
}
void printHelloWorld()
{
printf("hello\n");
printf("world");
}
int main()
{
replaceStdout();
printHelloWorld();
restoreStdout();
// Use outputBuffer to test EXPECT_EQ("somthing1", outputBuffer);
printf("Fetched output: (%s)", outputBuffer);
return 0;
}
参考文献:http://kaskavalci.com/redirecting-stdout-to-array-and-restoring-it-back-in-c/
我正在尝试使用 googletest 创建一个测试器。问题是我正在测试的函数返回 void 并打印结果。我想将最后一个字符串打印到控制台中,以便我可以测试输出。该字符串可能包括 \n
.
所以我有函数本身:
void f_sequence(char sequenceStr[])
{
//logic...
if(condotion1)
printf("somthing1");
else if(condotion2)
printf("somthing2")
(...)
}
然后是测试人员:
TEST(TesterGroup, TesterName)
{
f_sequence("input");
EXPECT_EQ("somthing1", /*how do i get the output?*/);
}
可能吗?
我测试的函数是用 c 编写的,而测试函数本身(测试器)是用 c++ 编写的。使用 printf
打印输出。我无法更改功能本身。我正在使用 CLion 最新版本。
我不知道是否有可能获得最后打印的内容,但是如果您在调用测试函数之前控制环境,您可以重定向标准输出的位置,它允许您将其写入一个文件,然后您可以检查它。
请参阅 this old answer 哪个 IMO 被忽略了。它的例子在这里修改:
FILE *fp_old = stdout; // preserve the original stdout
stdout = fopen("/path/to/file/you/want.txt","w"); // redirect stdout to anywhere you can open
// CALL YOUR FUNCTION UNDER TEST HERE
fclose(stdout); // Close the file with the output contents
stdout=fp_old; // restore stdout to normal
// Re-open the file from above, and read it to make sure it contains what you expect.
两种方式:
如果您使用的是 POSIX 兼容系统,您可以使用 >
将程序的输出重定向到一个文件,然后稍后从文件中读取以确认输出是正确的.
另一种方式是这样的:
freopen("output.txt", "w", stdout);
f_sequence();
freopen("/dev/tty", "w", stdout);
用于 POSIX 兼容系统。在其他平台上,您需要将 "/dev/tty"
更改为其他内容。我不知道执行此操作的完全便携方式。
然后阅读output.txt
。上面的代码片段所做的是改变 stdout
是什么,以便它打印到一个文件而不是普通的标准输出。
一个解决方案:您可以编写一个单独的程序来执行该功能,并且在单元测试中,您可以将该程序作为子进程执行并检查输出。这可以用 std::system
来完成,但要非常小心,不要将任何非常量输入传递给它。即使在单元测试中,您也不希望 shell 注入漏洞。存在避免在子进程中使用 shell 的系统特定函数。
另一种解决方案,至少在 POSIX 上可行:用文件描述符替换标准输出/错误流,然后读取文件。
Googletest 特定:似乎有 testing::internal::CaptureStdout
,它似乎实现了替换标准流的想法。但正如命名空间所暗示的那样,这不是官方的 API,因此将来可能会更改。
C
中有一个 API 调用 ( cmd_rsp
) with source code here 的解决方案,当在您的程序中调用时,会创建一个单独的进程,并通过管道连接到 stdin
和 stdout
,它通过自动调整大小的缓冲区从中接受命令和 returns 响应。在概念上类似于 popen(...)
。
一个简单的用例:
char *buf = NULL;
/// test cmd_rsp
buf = calloc(BUF_SIZE, 1);
if(!buf)return 0;
if (!cmd_rsp("dir /s", &buf, BUF_SIZE))//note the first argument can be any legal command that
//can be sent via the CMD prompt in windows,
//including a custom executable
{
printf("%s", buf);
}
else
{
printf("failed to send command.\n");
}
free(buf);
将标准输出重定向到缓冲区。
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int stdoutSave;
char outputBuffer[BUFFER_SIZE];
void replaceStdout()
{
fflush(stdout); //clean everything first
stdoutSave = dup(STDOUT_FILENO); //save the stdout state
freopen("NUL", "a", stdout); //redirect stdout to null pointer
setvbuf(stdout, outputBuffer, _IOFBF, 1024); //set buffer to stdout
}
void restoreStdout()
{
freopen("NUL", "a", stdout); //redirect stdout to null again
dup2(stdoutSave, STDOUT_FILENO); //restore the previous state of stdout
setvbuf(stdout, NULL, _IONBF, BUFFER_SIZE); //disable buffer to print to screen instantly
}
void printHelloWorld()
{
printf("hello\n");
printf("world");
}
int main()
{
replaceStdout();
printHelloWorld();
restoreStdout();
// Use outputBuffer to test EXPECT_EQ("somthing1", outputBuffer);
printf("Fetched output: (%s)", outputBuffer);
return 0;
}
参考文献:http://kaskavalci.com/redirecting-stdout-to-array-and-restoring-it-back-in-c/