GVKun编程网logo

为什么循环条件内的 iostream::eof 被认为是错误的(即 `while (!stream.eof())`)?

18

最近很多小伙伴都在问为什么循环条件内的iostream::eof被认为是错误的和即`while(!stream.eof())`?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展.N

最近很多小伙伴都在问为什么循环条件内的 iostream::eof 被认为是错误的即 `while (!stream.eof())`?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例、.stream()和Stream.of有什么区别?、c – 为什么’ifstream’和’ofstream’添加到“std”,而’fstream’可以用于这两个目的?、c – 为什么我要单独包含iostream和ostream?等相关知识,下面开始了哦!

本文目录一览:

为什么循环条件内的 iostream::eof 被认为是错误的(即 `while (!stream.eof())`)?

为什么循环条件内的 iostream::eof 被认为是错误的(即 `while (!stream.eof())`)?

我刚刚在答案中发现了一条评论,说iostream::eof在循环条件中使用“几乎肯定是错误的”。我通常使用类似的东西while(cin>>n)-
我猜它会隐式检查 EOF。

为什么检查 eof 显式使用while (!cin.eof())错误?

它与scanf("...",...)!=EOF在 C 中使用(我经常毫无问题地使用)有什么不同?

答案1

小编典典

因为iostream::eof只会在读取流的末尾true 后返回。 它并不 表示 下一次读取将是流的结尾。

考虑一下(并假设下一次读取将在流的末尾):

while(!inStream.eof()){  int data;  // yay, not end of stream yet, now read ...  inStream >> data;  // oh crap, now we read the end and *only* now the eof bit will be set (as well as the fail bit)  // do stuff with (now uninitialized) data}

反对这一点:

int data;while(inStream >> data){  // when we land here, we can be sure that the read was successful.  // if it wasn''t, the returned stream from operator>> would be converted to false  // and the loop wouldn''t even be entered  // do stuff with correctly initialized data (hopefully)}

关于你的第二个问题:因为

if(scanf("...",...)!=EOF)

是相同的

if(!(inStream >> data).eof())

一样

if(!inStream.eof())    inFile >> data

.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例

.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例

一、FileStream文件流

1.读取数据

 1    public class ReadFile
 2     {
 3         /// <summary>
 4         /// 读取文件
 5         /// FileMode.Create  创建一个新文件,如果文件已经存在则改写旧文件
 6         /// FileMode.CreateNew 创建一个文件,如果文件存在会发生异常,提示文件已经存在
 7         /// FileMode.Open  打开文件,如果文件不存在则异常
 8         /// FileMode.OpenOrCreate  打开文件,如果文件不存在,则创建一个新的文件并且打开文件
 9         /// FileMode.Append   打开现有文件,并且在现有文件内容后面追加,如果文件不存在则异常
10         /// FileMode.Truncate 根据现有操作系统,截取文件里面的内容,如果文件不存在则异常
11         /// </summary>
12         public static void Read(string FilePath)
13         {
14             FileStream fileStream = null;
15             try
16             {
17               fileStream = new FileStream(FilePath, FileMode.Truncate);
18                 byte[] bytes = new byte[fileStream.Length];
19                 int read = fileStream.Read(bytes, 0, bytes.Length);
20                 var result = Encoding.UTF8.GetString(bytes);
21             }
22             catch (Exception e)
23             {
24                 if (fileStream != null)
25                 {
26                     fileStream.Dispose();
27                 }
28                 Console.WriteLine(e.Message);
29             }
30             finally
31             {
32                 if (fileStream != null)
33                 {
34                     fileStream.Close();
35                     fileStream.Dispose();
36                 }
37             }
38         }
39     }

2.写入数据

 1    public class WriteFile
 2     {
 3         public static void WriteText(string FilePath,string writeString)
 4         {
 5             FileStream fileStream = null;
 6             try
 7             {
 8                 //根据路径打开文件
 9                 fileStream = new FileStream(@"C:\Users\Administrator\source\repos\OperatFile\OperatFile\1.txt", FileMode.Append);
10                 //把字符串转化成字节
11                 byte[] bytes = Encoding.UTF8.GetBytes(writeString);
12                 //写入到文件
13                 fileStream.Write(bytes, 0, bytes.Length);
14             }
15             catch (Exception e)
16             {
17           if (fileStream != null)
18                 {
19                     fileStream.Dispose();
20                 }
21                 Console.WriteLine(e.Message);
22             }
23             finally
24             {
25                 //关闭和释放
26                 if (fileStream != null)
27                 {
28                     fileStream.Close();
29                     fileStream.Dispose();
30                 }
31             }
32         }
33     }

二、StreamReader文本流

1.读取数据

 1    public class SteamReadFile
 2     {
 3         /// <summary>
 4         /// 读取文件
 5         /// </summary>
 6         /// <param name="filePath">文件路径</param>
 7         public static void ReadFile(string FilePath)
 8         {
 9             try
10             {
11                 using (StreamReader sr = new StreamReader(FilePath))
12                 {
13                     var result = sr.ReadToEnd();
14                     Console.WriteLine(result);
15                 }
16             }
17             catch (Exception e)
18             {
19 
20                 throw new Exception(e.Message);
21             }
22         }
23     }

2.写入数据

 1    public class StreamWriteFile
 2     {
 3         /// <summary>
 4         /// 写入文件
 5         /// </summary>
 6         /// <param name="FilePath">文件路径</param>
 7         /// <param name="WriteString">待写入字符串</param>
 8         public static void WriteFile(string FilePath,string WriteString)
 9         {
10             try
11             {
12                 using (StreamWriter sr = new StreamWriter(FilePath))
13                 {
14                     sr.WriteLine(WriteString);
15                 }
16             }
17             catch (Exception e)
18             {
19                 throw new Exception(e.Message);
20             }
21         }
22     }

3.写入日志实例

 1    public class LogHelper
 2     {
 3         /// <summary>
 4         /// 文件路径
 5         /// </summary>
 6         public static string FilePath = @"C:\Users\Administrator\source\repos\OperatFile\OperatFile\Files";
 7         static LogHelper()
 8         {
 9             //判断文件夹是否存在,如果不存在,则重新创建
10             if (!Directory.Exists(FilePath))
11             {
12                 Directory.CreateDirectory(FilePath);
13             }
14         }
15      /// <summary>
16         /// 日志写入
17         /// Path.Combine(str1,str2,str3)  把传入的参数拼接起来,然后返回新的字符串
18         /// File.AppendText(fullPath) 根据文件路径,把新写入的内容,拼接到文本后面
19         /// </summary>
20         public static void WriteLog()
21         {
22             try
23             {
24                 var sb = BindData();
25                 string fullPath = Path.Combine(FilePath, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
26                 //判断文件是否存在,如果不存在,则新建文件
27                 if (!File.Exists(fullPath))
28                 {
29                     File.Create(fullPath);
30                 }
31                 using (StreamWriter sw = File.AppendText(fullPath))
32                 {
33                     sw.WriteLine(sb.ToString());
34                 }
35             }
36             catch (Exception e)
37             {
38                 throw new Exception(e.Message);
39             }
40 
41         }
42      /// <summary>
43         /// 绑定日志信息
44         /// </summary>
45         /// <returns></returns>
46         private static StringBuilder BindData()
47         {
48             StringBuilder sb = new StringBuilder();
49             DateTime operatDateTime = DateTime.Now;
50             string content = "读写文件功能";
51             string operators = "小明";
52             sb.AppendLine($"操作时间:{operatDateTime}");
53             sb.AppendLine($"操作内容:{content}");
54             sb.AppendLine($"操作人:{operators}");
55             sb.AppendLine("------------------------------------------------------------------------------------------");
56             return sb;
57         }
58     }

三、MemoryStream内存流

 1      /// <summary>
 2         /// 根据URL读取内容到内存流
 3         /// </summary>
 4         /// <param name="url"></param>
 5         /// <returns></returns>
 6         public static string DownLoadByUrl(string url)
 7         {
 8             string result = string.Empty;
 9             MemoryStream ms = null;
10             HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
11             HttpWebResponse response = request.GetResponse() as HttpWebResponse;
12             using (var stream = response.GetResponseStream())
13             {
14           byte[] buffer = new byte[response.ContentLength];
15                 int actuallyRead = 0, offset = 0;
16                 do
17                 {
18                     actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
19                     offset += actuallyRead;
20 
21                 } while (actuallyRead > 0);
22                 ms = new MemoryStream(buffer);
23                 ms.Seek(0, SeekOrigin.Begin);
24                 var byteArray = new byte[ms.Length];
25                 ms.Read(byteArray, 0, byteArray.Length);
26                 result = Encoding.UTF8.GetString(byteArray);
27             }
28             response.Close();
29             response.Dispose();
30             return result;
31         }

 

.stream()和Stream.of有什么区别?

.stream()和Stream.of有什么区别?

这是从集合中创建流的最佳方法:

    final Collection<String> entities = someService.getArrayList();
  1. entities.stream();

  2. Stream.of(entities);

答案1

小编典典

第二个没有按照您的想法做!它并 没有 给你的集合中的元素流; 相反,它将为您提供具有单个元素的流,该元素是集合本身(而不是其元素)。

如果需要包含集合元素的流,则必须使用entities.stream()

c – 为什么’ifstream’和’ofstream’添加到“std”,而’fstream’可以用于这两个目的?

c – 为什么’ifstream’和’ofstream’添加到“std”,而’fstream’可以用于这两个目的?

使用std :: fstream可以声明类型为ifstream和ofstream的对象.唯一的区别是,使用fstream,我们需要提供in,out,app作为参数,可能并不总是需要其他两个.

有没有什么特别的ifstream,流不能用fstream或只是编码方便?

解决方法

这有点像是为什么我们想要const,当你可以读取和写入变量.它允许编译时检查,这是减少错误的一个非常宝贵的功能.它也是更自我的文档,因为当查看一个没有构造函数调用的声明时,您可以看到它是一个输入,输出还是两者:您提到的参数通常只能在实现文件中看到,而这些参数可能无法实现.此外,每种类型的流可能在他们需要的数据成员中有一些差异 – 可能使用符合您实际需要的最小功能类可以节省内存,时间初始化或检查其他变量等.

c – 为什么我要单独包含iostream和ostream?

c – 为什么我要单独包含iostream和ostream?

参见英文答案 > iostream vs ostream what is different?5个
我注意到许多人分别在C程序中包含iostream和ostream,如下所示:
#include <iostream>
#include <ostream>
int main()
{
}

为什么有人这样做?由于iostream继承自ostream,它应该包含其中的所有内容,对吧?有一些不明原因吗?简单(std :: cout)代码怎么样?

解决方法

尽管stringstream继承自iostream,但它并未在< iostream>中声明.头. < iostream> header包含iostream类型的定义以及着名的cout,cerr,cin和clog类型,但不包含其他类型的iostream(例如,文件流).对于这些,您需要显式#include必需的头文件.

编辑:在回答您修改后的问题时,我提出了C规范,有趣的是它没有说< iostream>必须包括< ostream>或者< istream>.实际上,只需包含< iosfwd>就可以逃脱.因此,可以#include< iostream>没有实际获得istream或ostream的完整类定义.只有明确包含这些头文件才能保证这些类的定义,而不仅仅是前向声明,是可见的.

关于为什么循环条件内的 iostream::eof 被认为是错误的即 `while (!stream.eof())`?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例、.stream()和Stream.of有什么区别?、c – 为什么’ifstream’和’ofstream’添加到“std”,而’fstream’可以用于这两个目的?、c – 为什么我要单独包含iostream和ostream?等相关知识的信息别忘了在本站进行查找喔。

本文标签: