fscanf c ++等价物

时间:2012-04-23 15:21:52

标签: c++ c

我想将以下C代码翻译成C ++。

FILE *fp = NULL;
fp = fopen("./filename", "r");
int i = 0;
fscanf(fp, "%d\n", &i);
uint16_t j = (uint16_t) i;

这就是我提出来的:

  ifstream file;
  string filename = "./filename";

  file.open(filename.c_str(), ios::in);
  errno = 0;
  if (file.fail()) {
      int tmp = errno;
      std::cout << file.c_str () << " not found: strerror(" << tmp << "): " << strerror(tmp) );
  }
  int i = 0;
  file >> i >> std::endl;       
  uint16_t j = (uint16_t) i;

我想知道语法是正确的还是可以改进的,更重要的是它是否可以安全地抵御各种输入。

2 个答案:

答案 0 :(得分:2)

int read_int(const std::string file_name) {
    std::ifstream file(file_name); //the file will close itself on destruction
    std::uint16_t i;
    //extract type, don't worry about what it is it will either compile or not
    if(!(file >> i)) { //Catch failure
         //or however you wish to deal with it.
         throw std::runtime_error("can't read file");
    }
    return i;
}

int main() {
    try{
        std::uint16_t i=read_int("./filepath");
        //do with i...
    }
    catch(const std::exception& e) {
         std::cerr << e.what() << std::endl;
         return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

请注意,如果您没有C ++ 11,则需要使用c_str()打开文件,但首选字符串方法。

编辑:fstream关闭自己,没有必要自己关闭它,功能是你必须这样做但是依赖RAII语义要好得多:

http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

RAII规定你应该在构造时打开文件,它会在破坏时关闭,这可以确保没有任何无效(排除EOF,文件未找到...)fstream对象防止错误。 RAII是C ++中的基本结构,应该在涉及资源的地方使用。

fstream析构函数的文档在这里:

http://en.cppreference.com/w/cpp/io/basic_fstream

  

破坏basic_fstream和相关缓冲区,关闭文件

答案 1 :(得分:2)

确切的等价物是:

std::ifstream fs( "./filename" );
int i = 0;
fs >> i >> std::ws;
uint16_t j = i;

这是否是你真正想要的另一个问题:使用a "\n"格式字符串中的fscanf建议(至少对我来说) 你真的想读一个'\n',而不是任意的空格; 然而,"\n"fscanf的含义是跳到下一个 非空白。 (在交互式输入的情况下,这可能是真实的 问题,因为你不会从scanf - 或我的。{ 替换上面 - 直到你遇到非白色空间 字符或文件结尾。对于来自文件的输入,它可能不是 问题。)

当读取面向行的输入时,经典的解决方案是使用 std::getline,然后std::istringstream来解析它。