【问题标题】:Why it refuses to write the binary of an integer to a file?为什么它拒绝将整数的二进制写入文件?
【发布时间】:2018-06-13 09:50:42
【问题描述】:

我遇到了这个问题 - 当我尝试将整数的二进制写入文件时,它不会将其写入 Delivery 文件中。

我的整个想法是获取整数,将其转换为二进制,然后将其写入文件。之后,如果需要,我会回到程序中,写入一个新的整数值,然后将新值添加到已经写入的值中。即文件中的“5”,回来,写“3”,然后文件中有8。

代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

char answer;

struct PRODUCT {
    string product_name;
    int quantity;
    PRODUCT() : product_name(""), quantity(0) {}
} product;

int main () {
    fstream delivery_file("files/Delivery", ios::app | ios::in | ios::out | ios::binary);
    do {

        if (delivery_file.is_open()) {
            cout << "\nPlease input the name of a product: ";

            getline(cin, product.product_name);

            cout << "\nPlease input the quantity of a product: ";
            string str;
            getline(cin, str);
            product.quantity = atoi(str.c_str());

            bool foundAndReplaced = false;

            while (!delivery_file.eof())
            {
                PRODUCT temp_prod;
                while (!delivery_file.eof())
                {
                    char ch = delivery_file.get();
                    temp_prod.product_name += ch;
                    if (ch == 0)
                    {
                        break;
                    }
                }
                if (delivery_file.eof() && delivery_file.tellg() == ios::beg)
                {
                    cout << "Error: Unexpected end of file.\n";
                    delivery_file.clear();
                    break;
                }
                if (temp_prod.product_name == product.product_name)
                {
                    delivery_file.seekp(delivery_file.tellg());
                    delivery_file.read((char*)(temp_prod.quantity), sizeof(PRODUCT::quantity));
                    product.quantity += temp_prod.quantity;
                    delivery_file.write((char*)(product.quantity), sizeof(PRODUCT::quantity));
                    foundAndReplaced = true;
                }
            }

            if (!foundAndReplaced)
            {
                delivery_file.write(product.product_name.c_str(), product.product_name.length() + 1);

                delivery_file.write((char*)(&product.quantity), sizeof(product.quantity));
            }

        }

        else {
            cout << "Unable to open file";
        }


        cout << "Do you want to add more products? Y/N \n";
        answer = 0;
        while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N')
        {
            answer = _getch();
        }
    }
    while(answer == 'Y' || answer == 'y');
    delivery_file.close();

    cout << "\nDeliveries registered.\n";

    return 0;
}

【问题讨论】:

  • 不要发布外部链接。这些可能会过时。在此处发布您的代码(编辑您的问题)。只需将其添加到问题中,选择代码并按下编辑器中的{} 工具栏按钮即可。这会将其格式化为代码。更多信息:meta.stackexchange.com/questions/22186/…。我从您的链接中复制了代码并将其发布在此处。下次,你应该自己做。

标签: c++ binary


【解决方案1】:

使用ios::binary 不会导致它将二进制数据写入文件,它只是禁用某些格式,例如参见What the point of using std::ios_base::binary?

如果您希望将整数作为二进制文件写入文件,我建议您使用以下内容:

int foo = 0x0F00;
ofstream bar("test.txt", ios::out | ios::binary);
bar.write(reinterpret_cast<char*>(&foo), sizeof(int));
bar.close();

这将采用整数,将其重新解释为字符序列并将其输出到文件而不进行格式化(为此需要ios::binary)。

看到你已经编辑了这个问题:你不能像这样在磁盘上求和,你只能以字节为单位写入,这将覆盖以前存在的任何数据。要做你想做的事,你必须阅读这个数字,总结它,然后再写下来。您可以通过使用 foo.read(...)foo 现在是 fstream 并使用 ios::in 打开来做到这一点。

【讨论】:

  • 我的整个想法是获取整数,将其转换为二进制,然后将其写入文件。之后,如果需要,我会回到程序中,写入一个新的整数值,然后将新值添加到已经写入的值中。即文件中的“5”,回来,写“3”,然后文件中有8。
  • 你不能写位。要执行您想要的操作,您必须读取该值,将它们相加然后再次写入,您可以使用bar.read(...) 执行此操作,但随后bar 应该是fstream 并且也使用ios::in 打开,很像你的例子。我只是展示了一个如何将二进制文件写入文件的最小示例。
  • 感谢您的评论。但是,您能否查看我在主帖中提供的来源,由于某种原因,它没有在“文件/交付”中写任何内容
  • 一般来说,我建议首先在最小的示例上测试新事物。只需滚动代码我会说您应该查看if (temp_prod.product_name == product.product_name) 之后的行,您需要将指针转换为指向指针而不是指向指针的值。现在您只需要存储地址(存储在文件中几乎没有意义)。另一个注意事项,当输出错误时,使用 cerr 而不是 cout,它没有被缓冲,所以它保证在出现任何严重错误之前执行。
猜你喜欢
  • 1970-01-01
  • 2015-01-30
  • 2012-03-03
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
相关资源
最近更新 更多