我想知道如何使用 char* 写入 char*,int,double 类型的数据,并再次使用 char* 逐行读取整个文件?我知道它可以用 std:string 来完成,真的很漂亮,但我对 char* 感兴趣。我创建了一个 Write() 方法,它成功地写入了 char* 但我不知道如何为整数和双精度调整它,我也开始创建 Read() 方法来读取每一行并将其保存到 char* 然后将其打印到控制台但我不知道如何实现它.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
void Write(char* fileName, char* pData)
{
ofstream file (fileName, ios::out | ios::app );
if (file.is_open())
{
size_t len = strlen(pData);
file.write(pData, len);
}
}
void Read(char* fileName, char* pData)
{
ifstream file(fileName, ios::in );
if(file.is_open())
{
file.read((char*)&pData, sizeof(pData));
file.close();
}
}
int main()
{
char* fileName = "E:\\cpp\\CarsIO\\data.txt";
char* data = "hello\n";
Write(fileName , data);
char* read = "";
Read(fileName , read);
return 0;
}
答案 0 :(得分:1)
我创建了一个 Write() 方法,它成功地写入了 char* 但我不知道如何针对整数和双精度调整它 [...]
首先,函数 std::ofstream::write
用于无格式(二进制)I/O。由于您正在输出文本,因此使用格式化的 I/O 函数会更容易,例如 operator <<
,如下所示:
void Write( char* fileName, char* pData )
{
ofstream file( fileName, ios::out | ios::app );
if ( file.is_open() )
{
file << pData;
}
if ( !file )
{
//TODO: handle error
}
}
为了让函数 Write
打印 int
类型的数据,您可以简单地创建一个合适的 overloaded 函数 Write
,如下所示:
void Write( char* fileName, int data )
{
ofstream file( fileName, ios::out | ios::app );
if ( file.is_open() )
{
file << data;
}
if ( !file )
{
//TODO: handle error
}
}
为了使它也打印数据类型 double
,您可以为该数据类型创建一个额外的重载函数。您可以简单地复制上面的函数并将 int data
更改为 double data
。
但是,现在您有 3 个重载函数,一个用于数据类型 char *
,一个用于 int
,一个用于 double
。那是很多不必要的代码重复。制作一个可以处理所有三种数据类型的单个模板函数会不那么混乱:
template <typename T>
void Write( char* fileName, T data )
{
ofstream file( fileName, ios::out | ios::app );
if ( file.is_open() )
{
file << data;
}
if ( !file )
{
//TODO: handle error
}
}
[...] 我也开始创建 Read() 方法来读取每一行并将其保存到 char* 然后将其打印到控制台,但我不知道如何实现它。
函数 std::ifstream::read
用于无格式(二进制)输入,而不是用于有格式文本输入。由于您坚持使用 char*
而不是 std::string
,我建议您使用函数 std::istream::getline
来准确读取一行文本输入,如下所示:
void Read( char* fileName, char* pData, std::streamsize count )
{
ifstream file(fileName, ios::in );
if(file.is_open())
{
file.getline( pData, count );
}
if ( !file )
{
//TODO: handle error
}
}
在您的代码中,您只是使用 sizeof(pData)
来传递内存缓冲区的大小。这将不起作用,因为这将为您提供指针 pData
的大小(可能是 4 或 8 个字节),而不是内存缓冲区的大小。这就是函数 Read
必须采用附加参数来指定内存缓冲区大小的原因。
在您的代码中,您像这样调用函数 Read
:
char* read = "";
Read(fileName , read);
这段代码是错误的,原因有两个:
您必须确保内存缓冲区足够大以存储读取的数据。这在使用 std::string
时会自动处理,但在使用 char*
时您必须自己处理。
行 char* read = "";
使指针 read
指向(空)字符串文字。字符串文字是只读的。这就是 C++ 要求将指向字符串文字的指针声明为 const char *
而不是 char *
的原因。您不能将指向只读字符串文字的指针传递给函数 Read
,因为该函数将尝试写入该字符串文字,从而导致 undefined behavior。
为了调用函数Read
并打印结果,可以使用如下代码:
char buffer[100];
Read( fileName, buffer, sizeof buffer );
std::cout << buffer << "\n";