簡體   English   中英

C ++隨機訪問文件

[英]C++ Random Access Files

這是我第一次在C ++中嘗試隨機訪問文件,但是我之前在Java中嘗試過它,但無法在C ++中使用它。 我的想法是要創建100個空記錄,然后將記錄存儲在文件中的特定記錄編號處。 這是我的代碼,我盡可能地簡化了代碼。

我這里有一個名為Tool的結構:

struct Tool {
    int number;
    char name[20];
    int quantity;
    double cost;
};

這是我的主要功能:

fstream outFile;
outFile.open("inventory.dat");

// Create 100 empty tool records
Tool tool;
tool.number = 0;
tool.name[0] = '\0';
tool.quantity = 0;
tool.cost = 0;  

for (int i = 0; i < 100; i++) {
    outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
    outFile.write(tool.name, sizeof(char)* 20);
    outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
    outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));
}

// Insert A tool record
Tool t;
t.number = 3;
t.quantity = 7;
t.cost = 57;
strcpy(tool.name, "Electric Sander");

outFile.seekp((tool.number - 1) * sizeof(Tool));
outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
outFile.write(tool.name, sizeof(char)* 20);
outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));

outFile.close();

我初始化100條空記錄的部分工作正常(假設我們要注釋代碼的插入部分。

但是,當執行插入部分時,我的程序會生成4 GB的數據。 我不確定發生了什么。 我感謝任何幫助。 提前致謝。

您可以編寫該結構的全部內容

    outFile.seekp(t.number*sizeof(Tool));
    outFile.write(reinterpret_cast<char *>(&tool),sizeof(Tool));

不要忘記告訴編譯器不要插入填充

#ifdef MSVC
#pragma pack(push,1)
#endif
struct Tool {
    int number;
    char name[20];
    int quantity;
    double cost;
#ifdef GCC
}__attribute__((packed));
#else
};
#endif

#ifdef MSVC
#pragma pack(pop)
#endif

資料來源:
https://codereview.stackexchange.com/questions/26344/writing-reading-data-structure-to-a-file-using-c
https://stackoverflow.com/a/18654265/194717
我們寶貴的成員的意見。

您使用了在最后一部分中表示t tool 尤其是:

outFile.seekp((tool.number - 1) * sizeof(Tool));

應該:

outFile.seekp((t.number - 1) * sizeof(Tool));

以及所有其他tool. 末尾的字段(假設您要使用t )。 tool.number為0,因此tool.number - 1為-1。 如果pos_type是無符號且為32位,則包裝的值會將您請求的位置放在4GB左右。

同樣,托馬斯·馬修斯(Thomas Matthews)在其評論中提出的對准點和托尼(Tony)在其回答中詳述的點對於確保文件中的數據正確也是很重要的。

在有關二進制模式的注釋中提到的Deduplicator和Galik點對於確保正確寫入數據也很重要。

這是一個替代方案:

struct Tool
{
    int number;
    char name[20];
    int quantity;
    double cost;
    void binary_write(std::ostream& out) const
    {
      out.write((char *) &number, sizeof(number));
      out.write((char *) &name[0], sizeof(name);
      out.write((char *) &quantity, sizeof(quantity));
      out.write((char *) &cost, sizeof(cost));
    }
    void binary_read(std::istream& inp)
    {
      inp.read((char *) &number, sizeof(number));
      inp.read((char *) &name[0], sizeof(name);
      inp.read((char *) &quantity, sizeof(quantity));
      inp.read((char *) &cost, sizeof(cost));
    }
    size_t binary_size(void) const
    {
      return sizeof(number) + sizeof(name)
             + sizeof(quantity) + sizeof(cost);
    }
};

int main(void)
{
  std::ofstream outfile("test.dat", ios::binary);
  if (!outfile)
  {
    cerr << "Error opening test.dat\n";
    return 1;
  }
  Tool t;
  for (unsigned int i = 0; i < 100; ++i)
  {
    t.binary_write(outfile);
  }
  outfile.close();
  std::ifstream in_file("test.dat", ios::binary)
  if (!in_file)
  {
    cerr << "Error opening test.dat for reading\n";
    return 2;
  }
  in_file.seekg(10 * t.binary_size(), ios::beg);
  t.binary_read(in_file);
  return 0;
}  

這里的概念是將讀寫功能放入對象中,因為該對象了解其成員,並且您可以從其他對象中隱藏數據(這是一件好事)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM