【问题标题】:char pointer file I/O字符指针文件 I/O
【发布时间】:2014-05-25 05:09:39
【问题描述】:

需要格式化,编辑需要一些时间。

【问题讨论】:

  • 人们在问题中编辑(损坏)代码建议使得其他人几乎不可能理解现有答案和 cmets,或者将问题描述与代码匹配。人们应该在他们的答案中发布更正的代码,或者如果 user2806369 想要 - 附加“工作版本”作为编辑问题。

标签: c++ file pointers char


【解决方案1】:

该文件只有 16 个字节,因为当您将 a.p 写入文件时,您正在写入一个指向内存中字符串的四字节指针值——您并没有写出字符串数据本身。

它看起来起作用的原因是您立即将相同的指针值读回同一进程中的另一个指针变量,因此当您读取 bp 指向的内存时,它与 bp 指向的内存相同ap,即以NUL结尾的字符串文本。

如果您创建了第二个程序,它只是读取文件,而不声明字符串文本,您应该会遇到错误,或者至少看不到文本。

int main() 
{
    string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");

    fstream fin(filepath,ios::in|ios::binary);

    struct block 
    { 
        int value; 
        int size; 
        const char* p; 
        int some;
    };

    block b;
    fin.read((char*)&b, sizeof(b)); 
    fin.seekg(0, ios::end);

    cout << "file size " << fin.tellg();
    fin.close();

    cout << "\n  size b " << sizeof(b);
    cout << "\n"<<b.value << "  " << b.size << "  " << b.p << "  " << b.some;
    getchar();  

    return 0;
}

【讨论】:

  • 解决方法,前提是我不允许更改结构块的成员变量。
  • 我不建议你改变struct block;我建议您尝试编译和运行类似于上面所附程序的程序。 (在编辑中)
  • 有几种不同的方法可以将字符串写入二进制文件;最常用的两个是只写以 NUL 结尾的字符串,例如fout.write(str.c_str(), str.length()+1)另外一个常用的选项是先写一个长度,再写字符串数据,可以终止也可以不终止:size_t s = str.length();fout.write(&amp;s, sizeof(s));fout.write(str.c_str(), s);
  • 但是这样我必须单独编写字符串,而不是完整的结构
  • 啊,我现在明白你的评论了。你在问,我该如何解决这个问题?如果您无法更改块的布局但可以添加成员函数,您可以添加一个operator &lt;&lt;(ostream&amp;),它首先写入 NUL 终止的数据或长度。如果你不能添加成员函数,你可以写一个 operator &lt;&lt;(ostream&amp; , struct block) 来做同样的事情。
【解决方案2】:

正如 Sam Mikes 所说,block.p 是指针,你只保存它的值(指针的值是它指向的内存的地址)并且因为 ap 仍然指向它在内存中,所以内存不会改变 add delete a; 喜欢下面的代码,看看不同

*注意:sizeof a 和 b 和 block 是一样的,你可以用sizeof(a) or sizeof(b) or sizeof(block) 代替

#include <string>
#include<iostream>
#include <fstream>
using namespace std;
int main(){
string text("C:\\Users\\Chitra\\Desktop\\Capture.JPG"); 
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fout(filepath,ios::out|ios::binary); 
fstream fin(filepath,ios::in|ios::binary);

struct block { 
   int value; 
   int size; 
   const char* p;
   int some;
};
block a;
a.value =1457745;
a.size=text.length();
a.p=text.c_str();
a. some=97877;

fout.write((char*)&a,sizeof(a)); 
fout.close();

delete a.p;

block b;
fin.read((char*)&b,sizeof(b)); 
fin.seekg(0,ios::end);
cout<<"file size "<<fin.tellg();
fin.close();
cout<<"\nsize a "<<sizeof(a)<<"  size b "<<sizeof(b)<<"  size block "<<sizeof (block);
cout<<"\n"<<b.value<<"  "<<b.size<<"  "<<b.p<<"  "<<b.some;
getchar();  
return 0;

}

【讨论】:

    【解决方案3】:

    你不能只是这样做......

    fout.write(pointer, bytes);
    

    ...对于pointerbyte任何 值,因为数据不存在于连续内存中。您必须分别写入不带指针的block 中嵌入的数据和指向的字符串数据。如果将指针移到结构的末尾,那是最简单的,然后写:

    struct block 
    { 
        int value; 
        int some;
        int size; 
        const char* p; 
    };
    
    fout.write((char*)&a, sizeof a - sizeof a.p);
               // could also "offsetof(block, p)" for size - possibly more fragile
    fout.write(a.p, a.size);
    

    然后,读取数据:

    block b;
    fin.read((char*)&b, sizeof b - sizeof b.p);
    b.p = new char[b.size + 1];
    fin.read(b.p, b.size);
    b.p[b.size + 1] = '\0';  // guarantee NUL termination
    

    稍后您需要delete[] b.p; 来释放new[] 返回的内存。或者,您可以使用另一个string

    block b;
    fin.read((char*)&b, sizeof b - sizeof b.p);
    std::string b_string(b.size, ' ');  // initially b.size spaces
    fin.read(&b_string[0], b.size);     // overwrite with data from the file...
    

    使用std::string,在调用析构函数时会自动进行解除分配。

    (实际上最好使用带有std::fstreams 的C++ 序列化库,例如boost's here。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 2012-10-30
      • 2017-04-25
      相关资源
      最近更新 更多