字符指针文件I/O



我很难理解程序的行为。test.txt文件有16个字节,其中由于结构的指针p所指向的文本大小超过16个字节(字符串文本),因此还有其他int值。如何将额外的数据存储在只有16个字节的测试文件中。该文件由另一个结构"b"读取,但它提供了正确的值,如"a"。

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();  
    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);
    cout << "n"<<b.value << "  " << b.size << "  " << b.p << "  " << b.some;
    getchar();  
    return 0;
 }

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

它之所以有效,是因为在同一进程中,您立即将相同的指针值读回另一个指针变量,因此当您读取b.p指向的内存时,它与a.p指向的存储器相同,即以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;
}

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

*注意:a、b和块的大小相同,可以使用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;

}

你不能只做…

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] = '';  // 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一样。)

相关内容

  • 没有找到相关文章

最新更新