鱼C论坛

 找回密码
 立即注册
查看: 1371|回复: 4

[已解决]快速入门C++第四节课后题求助

[复制链接]
发表于 2023-6-6 19:50:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

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

  11.     可以直接写成

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

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

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

  26.     int ch;

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

  32.     in.close();
  33.     out.close();

  34.     return 0;
  35. }
复制代码


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


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

感谢大家的回复[抱拳]
最佳答案
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 方法每次读取一个字符,不论这个字符是什么。以下是你的代码的修改版本:

  1. #include <iostream>
  2. #include <fstream>

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

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

  17.     char ch;
  18.     while(in.get(ch))
  19.     {
  20.         out << ch;
  21.     }

  22.     in.close();
  23.     out.close();

  24.     return 0;
  25. }
复制代码

这个修改后的版本应该能正确复制 First.txt 的全部内容,包括空格和换行符。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 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 方法每次读取一个字符,不论这个字符是什么。以下是你的代码的修改版本:

  1. #include <iostream>
  2. #include <fstream>

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

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

  17.     char ch;
  18.     while(in.get(ch))
  19.     {
  20.         out << ch;
  21.     }

  22.     in.close();
  23.     out.close();

  24.     return 0;
  25. }
复制代码

这个修改后的版本应该能正确复制 First.txt 的全部内容,包括空格和换行符。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

哇塞!
感谢!!!
然后我还有一个问题,就是
exit(EXIT_FAILURE);
这个部分被替换成了
return EXIT_FAILURE;
这俩没什么差别吧,都是退出程序的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 函数中的所有局部对象都被正确地析构。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

明白了。谢谢[鲜花]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 14:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表