【问题标题】:using fstream object to store information from a file into variables使用 fstream 对象将文件中的信息存储到变量中
【发布时间】:2012-10-16 20:36:03
【问题描述】:

我有以下代码块,用于读取以下格式的文本文件:

firstname lastname id mark
firstname lastname id mark

下面是代码块。

void DBManager::ReadFile(void){
fstream myfile; /*fstream object that will be used for file input and output operations*/
char* fn;       /*pointer to the storage which will hold firstname*/
char* ln;       /*pointer to the storage which will hold lastname*/
int id;         /*integer var to hold the id*/
float mark;     /*float var to hold the mark*/

/*read in the filename*/
g_FileName = new char[1024];                /*allocate memory on the heap to store filename*/
cout << "Please enter the filename:";
    cin >> g_FileName;

/*open file*/
myfile.open(g_FileName, ios::in | ios::out);

if(myfile.is_open()){   /*check if the file opening is successful*/
    cout << "File reading successful !\n";

    /*read information from the file into temporary variables before passing them onto the heap*/
    while (!myfile.eof()) {

        fn=(char*) new char[1024];
        ln=(char*) new char[1024];
        myfile >> fn >> ln >> id >> mark;
        cout << fn << " " << ln << " " << id << " " << mark << " " << endl;

    }
    myfile.close();
}
else{                   /*else print error and return*/
    perror("");
    return;
}

}

上面的代码块有效! :) 但是我很惊讶 myfile 是如何知道它应该一次保存一行的,以及它在设置四个变量方面如何足够聪明。

我是 C++ 新手,因此这可能包含在某种文档中。但我很乐意从您那里获得一些见解或链接到我可以更好地理解 fstream 对象的地方。

【问题讨论】:

    标签: c++ fstream


    【解决方案1】:

    我不确定问题是什么。但是,代码有几个问题:

    1. 您应该始终在尝试阅读后检查输入。
    2. 测试eof() 以确定是否还有更多内容无法阅读。
    3. 您有内存泄漏,在每个迭代器中分配内存。
    4. 在没有约束的情况下读取 char 数组是不安全的,即,它容易被缓冲区覆盖(主要攻击媒介之一)。

    您想使用如下所示的循环:

    std::string fn, ln;
    while (myfile >> fn >> ln >> id >> mark) {
         ...
    }
    

    【讨论】:

    • 嗨Dietmar,基本上我不确定我的代码是如何工作的.. myfile 是否自动配置为一次保存一行?
    • 输入并不真正关心行,而是将四个值读入变量并保存它们。如果这些值碰巧跨行拆分,它仍然会做同样的事情。请注意,您使用的值的分隔符是空格,即您的名字姓氏不能包含任何空格。
    • 感谢迪特玛!我知道现在发生了什么。感谢您的建议...作为学校作业,我们不必担心 1 和 4。但是我们被要求担心内存泄漏,我正在调用构造函数来创建一个带有这些临时变量的学生对象每次迭代。所以没有泄漏。当我将指向名字和姓氏的指针传递给构造函数时.. 关于 2. 为什么不检查 eof() 工作??
    • 如果你跳过 1. 你最终会处理最后一行两次!您在文件末尾进入循环并且不会读取任何新的内容,这些新内容通常看起来好像最后一行被处理了两次。关于指针,我强烈建议 not 使用指针,而是使用例如std::string。关于eof():如果任何输入无效,它可能永远不会被设置,从而提供无限循环。将eof() 用于循环控制通常是错误的。至少您需要确保跳过任何尾随空格。
    • 嗯,好吧,我明白你对 eof() 的看法,也许我应该用 good() 检查一下,我必须使用 char* .. 不允许使用字符串(学校作业!)我还是不明白你试图用 1 来指出……你能举个例子吗?
    【解决方案2】:

    在 C++ 中,std::fstream 是一种专门用于文件的流。从文件读取时,std::fstream 的接口与std::cin 几乎相同。当&gt;&gt; 运算符询问时,输入流被编程为读取下一个单词或数字。他们知道单词和数字在哪里,因为它们被空格隔开。在默认语言环境中,空格、制表符和换行符被视为空白。您可以更改语言环境以包含其他字符,例如逗号,并在读取文件时跳过这些字符。基本上,在使用输入流读取时,换行符和空格的处理方式相同。

    了解流的一些很好的解释在这里:http://www.cprogramming.com/tutorial/c++-iostreams.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      相关资源
      最近更新 更多