C ++检测输入是否不满足条件 [英] C++ Detect if input doesn't satisfy conditions

查看:67
本文介绍了C ++检测输入是否不满足条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:请通过清晰的答案和用法的小示例指导我

我正在从 binary 文件读取数据,其中第一个数字表示要读取的输入或值的数量,第二个数字表示第一个输入的长度,然后是输入本身,然后第二个输入的长度,然后是输入本身的长度,依此类推.

I am reading data from a binary file in which the first number indicates the number of inputs or values to read, the second tells the length of the first input then the input itself, after that the length of the second input then the input itself and so on.

所以写了以下代码:

    std::ifstream infile(filename, std::ios_base::binary);
    unsigned int NumberOfInputs;
    infile.read((char *) &NumberOfInputs, sizeof(unsigned int));

    for (unsigned int i = 0; i < NumberOfInputs; i++) {
        unsigned int Input_Lengh;
        infile.read((char *) &Input_Lengh, sizeof(unsigned int));
        string data;
        while (Input_Lengh) {
        char letter;
        infile.read((char *) &letter, sizeof(char));
        data += letter;
        Input_Lengh--;
        }
    }

但是如果文件损坏并且用户告诉我输入的数量是10,而我只读了2个(例如,因为我进入EOF)怎么办?

But what if the file was corrupted and the user told me that the number of inputs is 10 and I only read 2 (Because I got to EOF for example) How may I detect this?

推荐答案

来自文档. std :: istream :: read():

提取并存储字符,直到出现以下任何一种情况为止:

Characters are extracted and stored until any of the following conditions occurs:

  • 提取并存储了计数字符
  • 文件条件结束出现在输入序列上(在这种情况下,将调用 setstate(failbit | eofbit)).可以使用 gcount()查询成功提取的字符数.
  • count characters were extracted and stored
  • end of file condition occurs on the input sequence (in which case, setstate(failbit|eofbit) is called). The number of successfully extracted characters can be queried using gcount().

我做了一个小型的MCVE,以演示如何检查输入流的状态以及 std :: istream :: gcount():

I made a small MCVE to demonstrate how to check the state of input stream and the usage of std::istream::gcount():

#include <iostream>
#include <fstream>
#include <vector>

int main(int argc, char **argv)
{
  std::ifstream infile(argv[1], std::ios_base::binary);
  unsigned n;
  if (!infile.read((char*)&n, sizeof n)) {
    std::cerr << "ERROR! Failed to read number of inputs.\n";
    return 1;
  }
  for (unsigned i = 0; i < n; ++i) {
    unsigned len;
    if (!infile.read((char*)&len, sizeof len)) {
      std::cerr << "ERROR! Failed to read length of input " << (i + 1) << ".\n";
      return 1;
    }
    std::vector<char> data(len);
    if (!infile.read(&data[0], len)) {
      std::cerr << "ERROR! Failed to read data of input " << (i + 1) << ".\n"
        << "Expected " << len << " bytes but got " << infile.gcount() << ".\n";
      return 1;
    }
  }
  std::cout << "File '" << argv[1] << "' successfully read.\n";
}

测试:

$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp

$ echo "Good:" ; \
  echo -ne '\x01\x00\x00\x00\x04\x00\x00\x00''abcd' > test.dat ; \
  ./a.out test.dat
Good:
File 'test.dat' successfully read.

$ echo "Bad n:" ; \
  echo -ne '\x02\x00\x00\x00\x04\x00\x00\x00''abcd' > test.dat ; \
  ./a.out test.dat
Bad n:
ERROR! Failed to read length of input 2.

$ echo "Bad len:"; \
  echo -ne '\x01\x00\x00\x00\x04\x00\x00\x00''abc' > test.dat ; \
  ./a.out test.dat
Bad len:
ERROR! Failed to read data of input 1.
Expected 4 bytes but got 3.

在大肠杆菌上进行实时演示

注释:

  • unsigned 的大小取决于编译器/目标体系结构.可能少于4个字节.
  • unsigned 的终结点取决于平台.
    在此示例中,假定使用低端字节序,但仍然存在具有大端字节序的平台.
    (至少,在过去,平台具有更多的异国情调.)
  • The size of unsigned depends on the compiler / target architecture. It may be less than 4 bytes.
  • The endianess of unsigned is platform dependent.
    In this sample, little-endian is assumed but there are still platforms with big-endianess.
    (At least, in the past there were platforms with even more exotic endianess.)

要解决这两个问题,可以使用位算术运算符读取预期的字节数并将其组合为整数.

To fix both issues, the expected number of bytes can be read and composed to the integral using bit arithmetic operators.

相关问题/答案:

这篇关于C ++检测输入是否不满足条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆