【问题标题】:Read whether int or string using the file extraction operator使用文件提取运算符读取 int 或 string
【发布时间】:2015-09-26 01:40:58
【问题描述】:

我正在从文件中读取数据,并且正在使用提取运算符来获取第一个值。问题是我需要知道该值是 int 还是 string,以便将其放入适当的变量中。

所以我的问题是我可以尝试将它放入一个 int 中,如果它失败了,它会将它放入一个字符串中吗?还是事先检查它是 int 还是 string?

如果需要,我可以提供代码/伪代码。

文件示例:

   3 rows  3 columns all @ go
        5 columns 6  rows go
        5     rows        triangular        go
alphabetical   3 rows    3       columns go
 all !  4 rows  4 columns outer     go
 alphabetical      triangular       outer      5 rows   go

【问题讨论】:

  • “第一个值”是什么意思?例如,如果文件读取“foo.123”,“foo.123”是第一个值吗?或者是“foo”。第一个和“123”第二个?要不然是啥?您需要以足够的精度指定您想要的东西,否则您可以获得的唯一有用的答案是“完全实现您想要的任何东西”。
  • 第一个是 foo 然后是 123 像这样:edd 123 fed 1 dwd。我想看看哪个是字符串,哪个是整数。
  • 所以您想读取一系列由空格分隔的字符串,看看其中哪些仅由数字组成?
  • 我添加了一个文件可能是什么样子的示例。我通过文件提取运算符 inFile >> x; 读取它。所以它应该首先从那个文件中获取 2 我需要检查 3 是否是一个 int 然后移动到下一个,看看那是否是一个 int。这样我就可以正确地将它们放在适当的变量中。

标签: c++


【解决方案1】:

有很多方法可以做到这一点,一种是简单地将其读取为字符串,然后尝试在您自己的代码中将其解析为整数。如果解析成功,那么你有一个整数,否则你有一个字符串。

解析字符串有几种方法,包括(但不限于):

  • 使用std::istringstream>> 运算符,并检查流标志
  • std::stoi
  • 以编程方式检查所有字符是否都是数字,使用普通十进制算法进行转换。

使用std::stoi的简单示例:

std::string input;
if (std::getline(std::cin, input))
{
    try
    {
        std::size_t pos;
        int n = std::stoi(input, &pos);

        // Input begins with a number, but may contain other data as well
        if (pos < input.length())
        {
            // Not all input was a number, contains some non-digit
            // characters as position `pos`
        }
        else
        {
            // Input was a number
        }
    }
    catch (std::invalid_argument&)
    {
        // Input is not a number, treat it as a string
    }
    catch (std::out_of_range&)
    {
        // Input is a number, but it's to big and overflows
    }
}

如果您不想使用异常,则可以使用旧的 C 函数 std::strtol 代替:

std::string input;
if (std::getline(std::cin, input))
{
    char* end = nullptr;
    long n = std::strtol(input.c_str(), &end, 10);

    if (n == LONG_MAX && errno == ERANGE)
    {
        // Input contains a number, but it's to big and owerflows
    }
    else if (end == input.c_str())
    {
        // Input not a number, treat as string
    }
    else if (end == input.c_str() + input.length())
    {
        // The input is a number
    }
    else
    {
        // Input begins with a number, but also contains some
        // non-number characters
    }
}

【讨论】:

  • 对 stoi 和 istringstream 做了一些研究。你有没有机会给我一个例子来说明这可能是如何工作的?
【解决方案2】:

执行此操作的标准方法是提前 1 个字符

int nextInt()
{
   std::stringstream s;
   while (true) 
   {
       int c = getch();
       if (c == EOF) break;
       putch(c); // remove if you don't want echo

       if isDigit(c) 
          s << (char)c;
       else if (s.str().length() > 0)
           break;        
   }

   int value;
   s >> value;
   return value;
}

您应该能够将此示例转换为对文件中的所有“单词”重复该过程。

【讨论】:

  • 基本上,你要做的是......如果我刚刚得到一个 int,而下一个 char 不是一个 int(使用 peek)然后将一个 int 放到标准输出中,然后开始读取一个字符串。
  • 我正在读取文件而不是用户输入。说文件包含:tyyr 54 dhh 我想使用:myFile >> x 来抓取“tyyr”并检查它是否是 int。这将与 isdigit(x) 一起工作还是因为我试图将字符串放入 int var 而遇到编译问题?
  • @Duane:不要 4get 非数字可以以数字开头。
  • @SaladSnake 您一次只能读取一个字符。只有在你检查了 isdigit 之后才将它放在数字中。
  • 我用一个更好的例子替换了代码.. 也可以重新编写它以输出字符串......
猜你喜欢
  • 2021-12-23
  • 2011-11-18
  • 2018-01-03
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
相关资源
最近更新 更多