2011-06-21 31 views
11

我试图打开一个二进制文件进行写入而不擦除内容。但我不想写信给eof。我想写入文件中的特定位置。写入到现有的二进制文件的中间C++

这里是豆蔻例如:

ofstream out("test.txt", ios::binary | ios::app); 
for(int i = 0; i < 100; i++) 
    out.put('_'); 
out.write("Hallo", 5); 
out.close(); 

ofstream out2("test.txt", ios::binary | ios::app); 
out2.seekp(10); 
out2.write("Welt", 4); 
out2.close(); 

如果使用的应用程序,寻求不起作用。如果没有使用应用程序打开文件擦除数据。有人知道答案吗?

回答

10

尝试seekp第二个重载,它允许您提供偏移和方向,这可能会在你的情况下begining文件(即ios_base::beg)。这当然假设你知道你在做什么,你想要做的就是覆盖现有的字符数。

编辑:这里是完全工作的例子:

#include <iostream> 
#include <fstream> 

using namespace std; 
int main() 
{ 
    { 
    ofstream out("test.txt", ios::binary); 
    for(int i = 0; i < 100; i++) 
     out.put('_'); 
    out.write("Hallo", 5); 
    } 

    { 
    fstream out2("test.txt", ios::binary | ios::out | ios::in); 
    out2.seekp(10, ios::beg); 
    out2.write("Welt", 4); 
    } 
} 
+0

我刚试过out2.seekp(10,ios_base :: beg);.这并没有改变任何东西。 –

+0

它不应该擦除文件,除非你指定ios :: trunc – crashmstr

+0

@crashmstr,你是对的。我正在删除我的评论。 –

5

你不能神奇地从中间扩展文件。也许最容易写入新文件:首先复制初始段,然后写入新数据,然后复制剩余的段。全部完成后,您可以覆盖原始文件。

+0

我不想在中间扩展文件。我想覆盖初始值! –

+0

@Jonny:这不是你在你的问题中所说的。你说“没有删除内容”。否则,它是微不足道的,只是打开写入(没有“追加”),寻求开始和写。 –

+0

我不想写在开头。我想写在文件的某个地方。问题是再次打开文件将删除内容。 例如: 文件开头: ______________________操作后的文件:______Bla_______ –

5

的ios ::应用打开,这是因为如果你打开正好被附加到现有文件的新文件:你无法访问现有的文件。我不确定,因为我会像Kerrek的回答那样做,但是如果你真的想尝试,你可能必须打开“ios :: in | ios :: out”,类似于fopen(“test”)。 txt“,”rw“)。

或as crashmstr指出:ios :: out可能就足够了。

+4

你需要'ios :: out'和'ios :: in',否则,它只是覆盖methinks。 – Nim

+0

是的,因为'ios :: out'在Linux上导致以下类型的公开调用:O_WRONLY | O_CREAT | O_TRUNC,同时组合'ios :: out | ios :: in'会导致O_RDWR调用,而不会产生O_TRUNC。 – daminetreg

2

根据的fstream这里

fstream::open

的IOS ::应用规范“设置流的位置指示器每个输出操作前的数据流的结束。”所以ios :: app不能用于替换,至少对于我来说,任何排序都是失败的。

只是使用ios :: out会消除只保留大小的文件内容,基本上将文件转换为垃圾。

ios :: in | ios :: out原来是我唯一的工作。

0

工作代码:此代码在cout.exe中搜索字符串(OLD-STRING),并用新字符串(NEW-STRING)替换。

`#include "stdafx.h" 
#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    fstream ifs; 
    ifs.open ("C:\\Users\\user\\Desktop\\cout.exe", fstream::binary | fstream::in | fstream::out); 

    std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); 

    size_t pos = str.find("OLD-STRING"); 

    if (pos != string::npos) 
    { 
    cout << "string found at position: " << int(pos) << endl; 

    ifs.seekp(pos); 

    ifs.write("NEW-STRING", 10); 

    } 
    else 
    { 
    cout << "could not find string" << endl; 
    } 

    if (ifs.is_open()) 
    ifs.close(); 

    return 0; 
}`