首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以配置`stdin`读取c++字符串?

是否可以配置`stdin`读取c++字符串?
EN

Stack Overflow用户
提问于 2018-04-05 22:06:19
回答 1查看 617关注 0票数 1

我有很多用C编写的第三方函数,它们希望通过scanf()stdin获得输入。我已经用C++编写了其他调用c函数的函数。现在,我正在准备测试,我想用C++字符串编写输入测试用例。

所以我的问题是,是否有一种方式来表示stdin应该从C++字符串读取,而不是从标准输入中读取?如果我做到了这一点,那么我就可以编写几个输入为c++字符串的测试用例,并且我的C++函数将被透明地调用,这些函数调用c函数需要来自stdin的输入。

EN

回答 1

Stack Overflow用户

发布于 2018-04-06 18:18:05

我不确定这有多容易移植,但至少在Linux上的gcc-6.3中,你可以重新分配stdin指向不同的流,然后scanf()就会透明地使用它,就像它仍然在从终端读取一样。如果您想从一个预先存在的字符串中读取数据,可以使用类似于fmemopen()的方式打开新的流,这在POSIX系统上应该是可用的。这允许您从内存块(例如std::string的内容)创建FILE*

作为示例,下面的代码将scanf()字符串"String with 3.14159 * 2"中的五个值,就像它们是从终端输入的一样:

代码语言:javascript
复制
#include <cstdio>
#include <iostream>
#include <string>
#include <unistd.h>

int main(int argc, char *argv[])
{ const std::string input("String with 3.14159 * 2");
  char s0[16], s1[16], s2[8];
  double pi = 3; 
  int two = -2;

  { FILE *old_stdin = stdin;
    FILE* strm = fmemopen((void*)input.c_str(), input.size(), "r");
    stdin = strm;

    scanf("%s %s %lf %s %d", s0, s1, &pi, s2, &two);
    std::cout << "s0=\"" << s0 << "\" s1=\"" << s1 << "\""
              << " pi=" << pi << " s2=\"" << s2 << "\""
              << " two=" << two << std::endl;

    stdin = old_stdin;
    fclose(strm);
  }

  scanf("%12s", s0);
  std::cout << "Stdin: \"" << s0 << "\"" << std::endl;

  return 0;
}

这将生成以下输出:

代码语言:javascript
复制
s0="String" s1="with" pi=3.14159 s2="*" two=2

在将stdin返回到其正常行为之前,第二个scanf()等待来自终端的输入。

使用dup2() (就像使用here一样)尝试类似的方法是很有诱惑力的,但是对fmemopen()返回的值调用fileno()返回的文件描述符似乎是无效的(在我的系统上是-1 )。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49674407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档