铭凡 发表于 2023-6-6 19:50:27

快速入门C++第四节课后题求助

小甲鱼老师让我们写一个FileCopy.cpp程序,然后代码如下
#include <iostream>
#include <fstream>
#include <windows.h>

int main(int argc, const char *argv[], const char *envp[])
{
    std::ifstream in;
    std::ofstream out;

/*
    std::ifstream in;
    in.open("First.txt");

    可以直接写成

    std::ifstream in("First.txt");
*/

    in.open("First.txt", std::ios::in);
    if(!in)
    {
      std::cerr << "打开文件失败! " << std::endl;
      exit(EXIT_FAILURE);
    }

    out.open("Second.txt", std::ios::out);
    if(!out)
    {
      std::cerr << "打开文件失败! " << std::endl;
      exit(EXIT_FAILURE);
    }

    int ch;

    //out.seekp(std::ios::beg);//视频里边31:54是seekg
    while(in >> ch)
    {
      out << ch;
    }

    in.close();
    out.close();

    return 0;
}

问题1:为什么vscode里边的gcc编译的时候,提示如下报错?视频里边31:54是seekg而不是seekp(编译的时候是没有加注释的)
test03.cpp: In function 'int main(int, const char**, const char**)':
test03.cpp:43:9: error: 'std::ofstream' {aka 'class std::basic_ofstream<char>'} has no member named 'seekg'; did you mean 'seekp'?
   43 |   out.seekg(std::ios::beg);
      |         ^~~~~
      |         seekp

问题2:我在程序的根目录下创建了文件First.txt并且里边是有内容的,但是Second.txt文件却是空白的

感谢大家的回复[抱拳]

isdkz 发表于 2023-6-6 19:53:59

问题1的答案:
在你的代码中,你正在尝试使用 seekg 方法在一个 std::ofstream 对象上。 seekg 是一个针对输入流的方法,它用于设置"get"位置,这是下一次输入操作开始读取的位置。然而, std::ofstream 是一个输出流对象,所以它并不支持 seekg 方法。因此,你的代码在编译时报错。

你可能想要使用 seekp 方法,它是一个针对输出流的方法,用于设置"put"位置,即下一个输出操作开始写入的位置。但在这个案例中, seekp 或 seekg 的使用都不必要,因为你只是简单地将一个文件的内容复制到另一个文件,不需要重新设置读取或写入位置。

问题2的答案:
你的代码中, int ch 变量被用于存储从文件中读取的字符。然而,你使用了 in >> ch 作为循环条件。这个操作符 >> 是有格式的输入操作,它在读取整数时,会跳过空白字符(如空格,制表符,换行符等)。因此,只有当 First.txt 中的内容是数字时,你的代码才能正确复制它。并且如果 First.txt 中有多个数字之间用空格或换行符等分隔,你的代码也只会读取第一个数字,因为 >> 操作符会在遇到第一个非数字字符时停止读取。

如果你想要复制 First.txt 的所有内容,包括空格和换行符,你应该使用 get 方法替代 >> 操作符。 get 方法每次读取一个字符,不论这个字符是什么。以下是你的代码的修改版本:

#include <iostream>
#include <fstream>

int main(int argc, const char *argv[], const char *envp[])
{
    std::ifstream in("First.txt");
    if(!in)
    {
      std::cerr << "打开文件失败! " << std::endl;
      return EXIT_FAILURE;
    }

    std::ofstream out("Second.txt");
    if(!out)
    {
      std::cerr << "打开文件失败! " << std::endl;
      return EXIT_FAILURE;
    }

    char ch;
    while(in.get(ch))
    {
      out << ch;
    }

    in.close();
    out.close();

    return 0;
}

这个修改后的版本应该能正确复制 First.txt 的全部内容,包括空格和换行符。

铭凡 发表于 2023-6-6 20:00:20

isdkz 发表于 2023-6-6 19:53
问题1的答案:
在你的代码中,你正在尝试使用 seekg 方法在一个 std::ofstream 对象上。 seekg 是一个针对 ...

哇塞!
感谢!!!
然后我还有一个问题,就是
exit(EXIT_FAILURE);
这个部分被替换成了
return EXIT_FAILURE;
这俩没什么差别吧,都是退出程序的

isdkz 发表于 2023-6-6 20:01:52

铭凡 发表于 2023-6-6 20:00
哇塞!
感谢!!!
然后我还有一个问题,就是


是的,你的理解是正确的。 exit(EXIT_FAILURE) 和 return EXIT_FAILURE 都会导致程序终止并返回一个表示失败的状态码。它们之间的主要区别在于它们的作用范围。

return 是C++语句,用于从一个函数返回。在 main 函数中使用 return ,会导致程序终止并返回一个状态码。这是因为 main 函数是程序的入口点,从 main 函数返回意味着程序的结束。使用 return 语句退出 main 函数时,会执行所有在 main 函数中创建的对象的析构函数。

而 exit 是C库函数,用于无条件地终止程序。当调用 exit 时,程序会立即终止,不执行当前函数余下的代码,也不执行调用该函数的代码。使用 exit 函数时,会首先执行所有全局对象的析构函数,然后结束程序。

在你的代码中, exit(EXIT_FAILURE) 和 return EXIT_FAILURE 都可以用来表示打开文件失败,需要终止程序。但一般来说,如果你在 main 函数中,建议使用 return ,因为这更符合C++的风格,并且它会保证 main 函数中的所有局部对象都被正确地析构。

铭凡 发表于 2023-6-6 20:03:12

isdkz 发表于 2023-6-6 20:01
是的,你的理解是正确的。 exit(EXIT_FAILURE) 和 return EXIT_FAILURE 都会导致程序终止并返回一个表示 ...

明白了。谢谢[鲜花]
页: [1]
查看完整版本: 快速入门C++第四节课后题求助