2014-02-27 33 views
-2

这里是从A C A片断++教程:为什么在这里检查两次C++输入文件流?

// istream::get example 
#include <iostream>  // std::cin, std::cout 
#include <fstream>  // std::ifstream 

int main() { 
    char str[256]; 

    std::cout << "Enter the name of an existing text file: "; 
    std::cin.get (str,256); // get c-string 

    std::ifstream is(str);  // open file 

    while (is.good())   // loop while extraction from file is possible 
    { 
    char c = is.get();  // get character from file 
    if (is.good()) 
     std::cout << c; 
    } 

    is.close();    // close file 

    return 0; 
} 

通知is.good()while出现两次,第一次,然后用if

链接到例如:http://www.cplusplus.com/reference/istream/istream/get/

+4

这是C++中文件I/O的一个不好的例子。我不会推荐你找到这个程序的教程。 – 0x499602D2

+0

谨慎地阐述为什么? – jia103

+2

您应该在执行输入后检查输入是否成功。 'while'循环中的条件是在输入实际发生之前检查流是否为'good()'*。而且,'std :: string'是操作动态大小的字符串的首选结构,而不是需要使用'.get()','.getline()'等古代输入方法的C-style字符串,和他们各自的过载。 – 0x499602D2

回答

1

为什么C++输入文件流在这里检查两次?

事实是不必要检查两次。如果第二个内部if (is.good())通过,那么外部while (is.good())也将始终通过。代码的作者需要某种循环方式,并且他错误地认为while (is.good())是合适的条件,因为当流无法提取时,它会停止循环。但这只是一半。 while (is.good())永远不是执行提取的正确方法。

您必须首先执行输入,然后检查它是否成功。否则,可能会执行失败的提取,使用该提取的结果并从程序中接收不需要的行为。正确的方法是使用提取本身作为条件。输入操作员将返回流的引用,然后它会变成一个布尔值返回true,如果以前读suceeded,否则返回false:

while (is.get(c)) 
{ 
    std::cout << c; 
} 

变量c也没有外循环。您可以在块封闭while()循环或使用for()循环,而不是:

for (char c; is.get(c);) 
{ 
    std::cout << c; 
} 

但似乎这段代码试图写入从文件到标准输出的所有内容。读取一个字符的方式是这里显示的方式,但您也可以使用流迭代器或std::ostream::operator<<()的缓冲区过载。

我在这段代码中看到另外两个问题。即:

  • std::string是用于操纵动态大小的字符串,而不是C-风格的字符串,其需要使用过时的输入方法,如.get().getline()等,以及它们各自的过载的优选构建体。

  • 手动关闭文件通常是不需要的。该流将在其创建范围的末尾自行关闭。您可能只想自己关闭该文件,以检查它是否成功或使用不同的文件或openmode重新打开该流。

0

第一个是,在while (is.good()),检查它是否已经达到EOF(文件的结束)。如果没有,它不会进入while循环。一旦输入while(),这意味着至少有一个字符保留为char c = is.get();指令。

第二个if()所做的是不允许打印最后一个读取的字符,因为在char c = is.get();之后,该文件可能会达到EOF。如果是,则不打印字符。

例如,假设你有这样的文件:

"Just an example!" 

现在,如果你刚:

while (is.good())   // loop while extraction from file is possible 
{ 
    char c = is.get();  // get character from file 
    std::cout << c; 
} 

输出为:"Just an example! "。最后一个空格是EOF字符(这是读取的最后一个字符)。

但随着:

while (is.good())   // loop while extraction from file is possible 
{ 
    char c = is.get();  // get character from file 
    if (is.good()) 
     std::cout << c; 
} 

输出将是:"Just an example!",这是你希望它是什么。

相关问题