在 C++ 中使用 istringstream

2023-12-08

我有一些代码利用 fork、execlp 和 wait 来创建两个进程。目标是能够重复打印提示并让用户输入最多包含 4 个参数/选项的命令。

int main()
{
     string command, argument;
     istringstream iss(argument);

  do
  {
  //prompt user for command to run
  cout << "Enter command: ";
  cin >> command >> argument;

  int pid, rs, status;
 
  //fork will make 2 processes
  pid = fork();
  if(pid == -1) { perror("fork"); exit(EXIT_FAILURE); }

if(pid == 0) {
//Child process: exec to command with argument

//C_str to get the character string of a string
rs = execlp(command.c_str(), command.c_str(), argument.c_str(), (char*) NULL);
.
if (rs == -1) { perror("execlp"); exit(EXIT_FAILURE); }
} else {
   //Parent process: wait for child to end
   wait(&status);
      }
   } while(command != "exit");

   return 0;
}

我知道我当前的代码只能支持该命令的一个参数,但我不确定使用什么来指定 1 到 4 个参数。这时候我的朋友提到了std::istringstream,但是在研究它时,我不明白如何使用它来与程序的其余部分进行输入。有没有办法设置它或者有不同的方法来满足要求?


最常见的使用模式std::istringstream处理用户输入的方法是接受一行文本,然后对其进行处理。这可以避免当输入与您的预期不匹配或无法预测时可能出现的问题。

下面是一个简单的示例,它一次从 STDIN 读取一行,并将其处理为一个命令,后跟一个字符串向量作为参数。

for(std::string line; std::getline(std::cin, line); )
{
    std::istringstream iss(line);

    std::string command;
    if (iss >> command)
    {
        std::vector<std::string> args;
        for (std::string arg; iss >> arg; )
        {
            args.push_back(arg);
        }
        std::cout << "Received '" << command << "' with " << args.size() << " arguments\n";
    }
    else
    {
        std::cerr << "Invalid input" << std::endl;
    }
}

当然,您不需要读取字符串或将内容存储在向量中。这只是为了说明目的。

基本点是避免人们遇到的陷阱,其中最常见的是期望先前的流操作成功。当这个假设不成立时,天真的程序员会发现自己试图解析应该在前一行中传递的内容。


损坏的示例:

#include <iostream>

int main() {
    std::string command;
    while (std::cin >> command)
    {
        std::cout << "Got command: " << command << std::endl;
        if (command == "foo")
        {
            // 'foo' expects two integer arguments:
            int arg1, arg2;
            std::cin >> arg1 >> arg2;
            std::cout << command << ": " << arg1 << ", " << arg2 << std::endl;
        }
        else if (command == "bar")
        {
            // 'bar' expects one float argument:
            float arg1;
            std::cin >> arg1;
            std::cout << command << ": " << arg1 << std::endl;
        }
    }
    return 0;
}

在上面,假设用户感到困惑并“调用”foo带有一个浮点参数的命令,则下一个命令是有效的bar命令:

foo 42.0
bar 3.14

发生的情况如下:

  1. The foo处理程序将 arg1 读取为 42,然后无法读取下一个参数。流现在有错误。

  2. 在该处理程序期间没有对输入进行错误检查,因此现在存在未定义的行为输出值arg2.

  3. 当尝试读取下一个命令时,流已处于错误状态,因此循环终止。

因此,该程序的输出可能如下所示:

Got command: foo
foo: 42, -149017896

修复此问题无需istringstream这是可能的,但这是一种痛苦。流可能进入错误状态的原因有很多,而清除特定错误状态的错误标志只是为了解决这个问题,这会导致代码丑陋且可能容易出错。您不仅需要清除错误标志,还需要告诉流忽略该行中的任何剩余字符。您可能已经开始阅读next行而不自知。


更稳健的例子:

#include <iostream>
#include <sstream>

int main() {
    std::string command;
    for (std::string line; std::getline(std::cin, line); )
    {
        std::istringstream iss(line);
        if (!(iss >> command))
            continue;
        std::cout << "Got command: " << command << std::endl;
        if (command == "foo")
        {
            // 'foo' expects two integer arguments:
            int arg1, arg2;
            if (iss >> arg1 >> arg2)
            {
                std::cout << command << ": " << arg1 << ", " << arg2 << std::endl;
            }
        }
        else if (command == "bar")
        {
            // 'bar' expects one float argument:
            float arg1;
            if (iss >> arg1)
            {
                std::cout << command << ": " << arg1 << std::endl;
            }
        }
    }
    return 0;
}

现在,与上一个示例相同的输入将给出输出:

Got command: foo
Got command: bar
bar: 3.14

差异是:

  • Using istringstream,处理输入的任何错误都不会影响源流,因此前一行的失败不会导致问题。

  • 读取参数时会正确检查字符串流,从而允许可选的错误处理。

  • 如果在某些解析失败后,您决定尝试以不同的方式处理一行输入,那么使用另一个字符串流很容易做到这一点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++ 中使用 istringstream 的相关文章

  • 低级挂钩/SetWindowsHookEx lParam 自动重复?

    在这里阅读 Windows PC 上如何实现键盘自动重复 https stackoverflow com questions 876852 how is keyboard auto repeat implemented on a windo
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index
  • Xamarin 测试记录器选项有错误。无法记录自动化测试

    选项 gt Xamarin gt Xamarin Test Recorder 中的所有设置都有错误 我的桌面上安装了 Visual Studio 2015 企业版 以及 Xamarin 和 Xamarin Test Recorder 插件
  • 从 unsigned char* 到 char* 的转换无效

    这是一个代码 1 int main int argc char argv 2 3 signed char S psc 4 unsigned char U pusc 5 char C pc 6 7 C S 8 C U 9 10 pc psc
  • ASP.NET 如何在 Web API 中读取多部分表单数据?

    我将多部分表单数据发送到我的 Web API 如下所示 string example my string HttpContent stringContent new StringContent example HttpContent fil
  • 如何进行Visual Studio格式字典初始化?

    所有 Visual Studio 也包括 2012 不格式化以下内容 messageProcessor new Dictionary
  • 在 T4 代码生成中,如何从引用的程序集中获取类型?

    由于 T4 在项目上下文之外运行 因此我无权访问当前程序集或其他程序集 如何注册对引用程序集的访问 然后从中获取类型 我猜您想访问项目中建筑物的程序集 我在下面的示例代码中所做的是将一个名为 TestLib 的项目添加到我的解决方案中 我将
  • 仅针对某些异常类型中断

    我知道异常处理是一件非常重要的事情 我们在所有项目中都在这样做 主要原因是记录客户发生的错误 这工作正常 根本不是问题 但是 当我仍在使用 Visual Studio 编码和运行应用程序时 我根本不需要任何异常处理 我希望调试器正好停在应用
  • 如何检查给定调用站点的重载决策集

    如何检查重载解析集 我在多个调用站点中使用了 4 个相互竞争的函数 在一个调用站点中 我期望调用一个函数 但编译器会选择另一个函数 我不知道为什么 这不是微不足道的 为了了解发生了什么 我正在使用enable if disable if打开
  • WPF ComboBox 中具有本地化名称的枚举

    我有一个列出枚举的组合框 enum StatusEnum Open 1 Closed 2 InProgress 3
  • 如何按名字和姓氏排序,然后按 SamAccountName 排序,其中并非所有姓名都有名字和姓氏?

    目前 我有以下内容 来自 LDAP Get context based on currently logged on user PrincipalContext domainContext new PrincipalContext Cont
  • VS C# 中的依赖地狱,找不到依赖项

    我创建了一个图表 C 库 我们称之为chartlibrary 它本身依赖于多个第三方 dll 文件 在另一个可执行项目中 我们称之为chartuser 我参考了chartlibrary项目 两个项目位于 Visual Studio 中的同一
  • 多个包含带有变量定义的头文件

    我只是构建一个简单的 C 项目 代码如下所示 head h ifndef HEAD H define HEAD H int my var 100 endif src1 cpp include head h src2 cpp include
  • C# 中的类和模块有什么用

    有人可以解释一下类和模块之间的区别吗 你什么时候使用其中一种而不是另一种 我正在使用 C 更新 我的意思是相当于 VB 模块的 C 版本 这在很大程度上取决于您所指的 模块 Visual Basic 的模块 C 中没有真正等效的 VB Ne
  • 什么是 C++11 扩展 [-Wc++11-extensions]

    我需要一些帮助来了解此错误发生的位置 警告 非静态数据成员的类内初始化是 C 11 扩展 Wc 11 extensions 这是它来自的代码部分 typedef struct Hand bool straight false bool fl
  • 为什么将未使用的返回值转换为 void?

    int fn void whatever void fn 是否有任何理由将未使用的返回值强制转换为 void 或者我认为这完全是浪费时间 David s answer https stackoverflow com questions 68
  • 提升shared_from_this<>()

    有人可以用几句话概括一下如何提升shared from this lt gt 应该使用智能指针 特别是从使用绑定函数在 io service 中注册处理程序的角度来看 编辑 一些回复要求提供更多背景信息 基本上 我正在寻找 陷阱 即人们使用
  • 智能感知不显示评论

    如果我在 Visual Studio 2010 中输入类似的内容数据集1 我得到所有可用方法和属性的列表 智能感知 这很好用 但是 如果我在此列表中选择一个方法或属性 我不会得到 if 的描述 例如 如果我有类似的东西 public cla
  • 如何在c#中获取斐波那契数

    伙计们 我有一个关于斐波那契的问题 如何获得斐波那契数列 该数字也将以用户输入结束 例如 如果我输入 21 则输出必须为 0 1 1 2 3 5 8 13 21 这是我的代码 static void Main string args int
  • 使用 List.Contains 方法为 LINQ 构建表达式树

    Problem 我正在重构一些LINQ查询我们的 Web 应用程序中的多个报告 并且我尝试将一些重复的查询谓词移至它们自己的中IQueryable扩展方法 以便我们可以将它们重新用于这些报告以及将来的报告 正如您可能推断的那样 我已经重构了

随机推荐

  • android.database.sqlite.SQLiteException:靠近“Group”:语法错误(代码1):

    Error Caused by android database sqlite SQLiteException near Group syntax error code 1 while compiling create table Grou
  • C#/Native:使用 SCSI PassThrough 读取 HDD 串行

    我编写了三种利用本机的不同方法CreateFile and DeviceIoControl调用以检索 HDD 序列号 而不是型号 第一个使用S M A R T 第二个使用Storage Query第三个使用SCSI PassThrough
  • JSF 标签未呈现[重复]

    这个问题在这里已经有答案了 我正在启动一个 JSF 项目 这是我第一次使用 JSF 并且在呈现标签时遇到问题 我正在 Eclipse 中进行开发并使用 TomCat 作为服务器 我的login jsp 文件 https gist githu
  • 无法加载包“Microsoft.Net.Native.SharedLibrary-x64”

    我要更新Microsoft NETCore UniversalWindowsPlatform但它显示一个错误 Unable to load package Microsoft Net Native SharedLibrary x64 如果我
  • 为什么在销毁对象后使用该对象时没有收到异常?

    下面的代码工作得很好 但它不应该 当我单击 Button1 时 该对象首先被销毁 然后使用其值 并且我没有收到任何访问冲突或其他内容 更重要的是 乘法运算给出了正确的结果 这证明了Obj1没有被毁掉 但话又说回来 这也不是真的 因为当我关闭
  • 将 fileChooserParams 中的 mime 类型转换为 Intent.setType 的正确格式

    我正在尝试使用 Android 中的 WebView 上传文件 This is the code in use TargetApi Build VERSION CODES LOLLIPOP Override public boolean o
  • 在局部变量的嵌套函数内部使用“get”

    我从来没有完全理解嵌套函数和通过引用传递参数 我的策略通常是做类似的事情get variabletopassbyreference 在子函数内部来完成此操作 到目前为止 我一直将全局变量传递给函数 并且效果很好 今天 我尝试在函数内创建局部
  • 使用 JavaScript 将 Excel 转换为 PDF

    如何自动将 Excel 文档 文件 转换为 PDF 我正在尝试调整找到的解决方案here脱颖而出 到目前为止我有这个 var fso new ActiveXObject Scripting FileSystemObject var docP
  • 禁用 freemarker 日志

    我正在使用 Struts 2 0 11 2 但我不知道我的应用程序最近发生了什么变化 我收到了大量的 freemarker 日志 DEBUG 13201 freemark template simple hidden ftl en UTF
  • 如何将 LaTeX/amsmath 与 matplotlib 一起使用?

    当我尝试在 matplotlib 中使用 LaTeX amsmath 包时 出现了一系列难以理解的错误 有没有人能够让这样的事情发挥作用 如果是这样 我很想看一个例子 这是我尝试过的 import matplotlib from matpl
  • iPhone 上的 UIPopoverPresentationController 不产生弹出窗口

    我正在尝试实施新的UIPopoverPresentationController在我的 iPhone 应用程序中 使用 Objective C 我想要的是一个简单的弹出窗口 其中包含从启动按钮发出的表格视图 Edit 这是我的REVISED
  • Python 3.4.0 与 MySQL 数据库

    我已经安装了Python版本 3 4 0我想做一个使用 MySQL 数据库的项目 我下载并尝试安装MySQLdb 但对于这个版本的 Python 来说并不成功 有什么建议可以解决这个问题并正确安装吗 MySQLdb 不支持 Python 3
  • 为什么这个内存地址 %fs:0x28 ( fs[0x28] ) 有一个随机值?

    我编写了一段 C 代码 并将其反汇编并读取寄存器以了解程序在汇编中的工作原理 int test char this char sum buf 6 strncpy sum buf this 32 return 0 我一直在检查的代码片段是测试
  • Python:使用 isin 或 wkn 调用 pandas_datareader 或将其转换为股票代码?

    我有一份包含 ISIN 和 WKN 编号的股票清单 我的目标是使用 pandas datareader 获取该股票的历史数据 我的问题是 该功能例如 import pandas datareader as web stock web Dat
  • Android HttpPost:如何获取结果

    我一直在尝试发送 HttpPost 请求并检索响应 但即使我能够建立连接 我仍然不知道如何获取请求响应返回的字符串消息 HttpClient httpclient new DefaultHttpClient HttpPost httppos
  • 在 PHP 中从 MySQL 创建下拉菜单?

    我对 PHP 和 MySQL 有一定的经验 所以我有点掌握了一些东西 但是我有点试图得到一些可能超出我水平的东西 不太确定这方面的难度级别 基本上 我希望创建 2 个下拉菜单来删除 MySQL 表中用户的访问权限 因此 第一个下拉菜单将用于
  • solr 评分 - fieldnorm

    当我搜索 iphone 时 我有以下记录和分数 记录1 字段名称 显示名称 Iphone FieldName 名称 Iphone 11 654595 MATCH sum of 11 654595 MATCH max plus 0 01 ti
  • 在全屏 3D 应用程序中获取桌面屏幕截图

    使用全屏 3D 应用程序 例如游戏 时是否可以将桌面渲染为屏幕截图 或者游戏运行时Windows会关闭渲染引擎吗 我正在寻找将桌面渲染为游戏中纹理的方法 类似 RDP 的协议可以作为解决方案吗 编辑 为了澄清 是否有任何深层 API 机制可
  • 如何从 TOleContainer 中提取图元文件?

    我有一个带有 TOleContainer 控件的 Delphi BDS 2006 应用程序 它内部有一个 OLE 对象 即 MS Office 2003 中的 MS Equation 公式 名称 Equation 3 如何从公式图像中提取矢
  • 在 C++ 中使用 istringstream

    我有一些代码利用 fork execlp 和 wait 来创建两个进程 目标是能够重复打印提示并让用户输入最多包含 4 个参数 选项的命令 int main string command argument istringstream iss