如何从c ++中的指定格式获取某些信息?

时间:2015-06-18 04:55:16

标签: c++

初级程序员在这里, 假设我想以(x,y)形式获取初始起始坐标,因此我要求用户使用特定形式"(x,y)"输入一个点。有没有办法可以识别格式并解析字符串,以便我可以获得x和y值?

3 个答案:

答案 0 :(得分:1)

使用以下方式阅读一行文字:

char line[200]; // Make it large enough.
int x;
int y;

fgets(line, sizeof(line), stdin);

然后,使用sscanf读取文本行中的数字。

if ( sscanf(line, "(%d,%d)", &x, &y) != 2 )
{
   // Deal with error.
}
else
{
   // Got the numbers.
   // Use them.
}

如果您想使用iostream而不是stdio,请使用getline代替fgets

答案 1 :(得分:0)

您可以使用正则表达式在输入中的任何位置查找匹配序列。

#include <iostream>
#include <string>
#include <regex>

int main() {
  std::string line;
  std::getline(std::cin, line);

  std::regex e(R"R(\(([-+]?(?:\d*[.])?\d+)\s*,\s*([-+]?(?:\d*[.])?\d+)\))R");

  std::smatch sm;
  if (std::regex_search(line, sm, e)) {
    auto x = std::stod(sm[1]);
    auto y = std::stod(sm[2]);
    std::cout << "Numbers are: " << x << ", " << y << std::endl;
  }

  return 0;
}

答案 2 :(得分:0)

为了解析东西,你需要一个解析器。编写解析器的方法有很多种,但通常解析器会读取令牌,并根据它的令牌决定下一步做什么。 (强调词语很重要,请查阅它们)。

在您的情况下,您不必明确引入单独的令牌实体。使用>>运算符从输入流中读取元素即可。

你需要:

  • 读一个字;验证它是'('
  • 读一个数字
  • 读一个字;验证它是','
  • 读一个数字
  • 读一个字;验证它是')'

如果任何步骤失败,则整个解析失败。

您可以看到相同的基本步骤已完成三次,因此您可以为其编写一个函数。

bool expect_char(std::istream& is, char what)
{
  char ch;
  return is >> ch && ch == what;
}

这是因为is >> ch在读取操作之后返回流,并且流可以被视为布尔值:true如果上一次操作成功,则false

现在您可以编写解析器了:

bool get_vector (std::istream& is, int& x, int& y)
{
   return expect_char(is, '(') &&
          is >> x              &&
          expect_char(is, ',') &&
          is >> y              &&
          expect_char(is, ')');
}

此方法有一个很好的属性,允许在数字和符号之间使用空格。

与使用sscanf的解决方案相比,现在这可能看起来像很多东西:

bool get_numbers2 (std::istream& is, int& x, int& y)
{
   std::string s;
   return std::getline(in, s) &&
          (std::sscanf(s.c_str(), "(%d,%d)", &x, &y) == 2);
}

但是sscanf是:

  • 危险(没有对其论点进行类型检查)
  • 功能不强(输入格式非常严格)
  • 不是通用的(不在模板中工作)

在适当的情况下使用scanf函数系列是可以的,但我不建议将其用于新的C ++程序员。