【问题标题】:Why do I get a run failed error after program runs and outputs as expected?为什么程序运行并按预期输出后出现运行失败错误?
【发布时间】:2019-03-28 17:38:09
【问题描述】:

我正在为 C++ 课程做一些功课,我被指示创建一个结构来保存 4 个公司部门的数据和每个季度的销售数据。我要将结构保存到二进制文件中,然后重新导入并读取数据。一切实际上都按预期运行,但是在输出后我得到一个 RUN FAILED, exit code 1 错误。

我最初认为这是由于某个地方的数组越界,但回头看代码我找不到它。

 * Author: James Hartley
 * Created on March 27, 2019, 10:09 PM
 * Description: Gaddis Ch.12 Problem 11-12 Corporate Sales Data Output/Input
 */

#include <iostream>
#include <fstream>

using namespace std;

struct division {
    string name;
    int qtrSales[4];
};

void structToFile(string fileName, division* div, int arySize) {
    fstream fileObject;
    fileObject.open(fileName, ios::out | ios::binary);
    fileObject.write(reinterpret_cast<char *>(div), sizeof(division) * arySize);
    fileObject.close();
}

void fileToStruct(string fileName, division* div, int arySize) {
    fstream fileObject;
    fileObject.open(fileName, ios::in | ios::binary);
    fileObject.read(reinterpret_cast<char *>(div), sizeof(division) * arySize);
    fileObject.close();
}

int main(int argc, char** argv) {
    division divs[4];
    division divsImport[4];
    divs[0].name = "East"; divs[1].name = "West"; divs[2].name = "North"; divs[3].name = "South";


    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            cout << "Please enter Quarter " << j+1 << " sales for " << divs[i].name << " division" << endl;
            cin >> divs[i].qtrSales[j];
        }
    }

    structToFile("struct.dat", divs, 4);
    fileToStruct("struct.dat", divsImport, 4);

    for (int i = 0; i < 4; i++) {
        cout << "Division: " << divsImport[i].name << endl;
        for (int j = 0; j < 4; j++) {
            cout << "Quarter: " << j+1 << endl;
            cout << "Sales: " << divsImport[i].qtrSales[j] << endl;
        }
    }
    return 0;
}

它输出正确,但是在输出后告诉我 RUN FAILED 退出代码 1。

【问题讨论】:

  • 这可能会有所帮助:stackoverflow.com/questions/523872/…
  • fileObject.write(reinterpret_cast&lt;char *&gt;(div), sizeof(division) * arySize); -- 你应该意识到这永远行不通。 sizeof() 是一个编译时值,为您提供该类型所包含的字节数。所以sizeof(division) 保持不变,不管std::string 对象中有多少个字符。字符串中可能有一千个字符,sizeof(division) 将保持不变。因此,无论您的 std::string 成员在其中有多少个字符,您都将(可能)向文件写入 40 字节左右的数据。
  • @PaulMcKenzie 谢谢你的详细回答,你很容易理解我做错了什么。感谢所有帮助。

标签: c++ file netbeans struct binary


【解决方案1】:

您的结构部门包含一个std::string,它不是一个可简单复制的类型。 std::string 通常包含指向动态内存分配的指针,这些指针仅在特定字符串对象存在时才有效。您不能简单地将构成std::string 对象的位写入磁盘,将其读回std::string 对象并期望有一个有效的std::string

【讨论】:

  • 这正是为什么reinterpret_cast 不适合这项工作的原因。这就是代码中一切都出错的地方。
  • 非常感谢您对字符串的解释!我只是将字符串更改为 char* 并且效果很好。此外, reinterpret_cast 是它告诉我在我的书中使用的内容。 Gaddis C++ 8th edition,还有哪些更好的选择?我知道这本书可能有点过时了
  • @JamesHartley -- 更改为 char * 并不能解决问题。也许您应该通过“更改为char *”来解释您的实际意思。 char * 是一个 4(或 8)字节的值——它不是 char 的数组。
  • @JamesHartley 不,那行不通。您正在写入指向文件的指针的值。你看到主要部分的评论和对象序列化的链接了吗?指针的大小通常为 4 或 8 个字节,因此 sizeof(division) 会让您陷入与答案所指出的相同的问题。如果有的话,你很幸运,你看到的东西看起来很有效。如果您需要证明,请让该指针指向具有 100 个字符数组的缓冲区。您不会在文件中看到该字符数组。
  • 是的,你需要序列化数据。换句话说,写入struct 代表的数据,而不是struct 本身。
猜你喜欢
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 2018-07-04
  • 2020-03-01
相关资源
最近更新 更多