简化文件读取的函数

function to simplify read from a file

本文关键字:函数 读取 文件      更新时间:2023-10-16

我想编写一个函数来简化file_in.get过程,这样我在读取文件时就不需要重复相同的行。但是我在实现它时遇到了麻烦。我唯一可以使用的库是<iostream><fstream><cstring><cctype>我想象的功能将是这样的:

void Link_Info::Read_Pointer()
{    
char temp[MAX]; 
file_in.get(temp, MAX, '~'); 
file_in.ignore(100, '~');
array = new char [ strlen(temp) + 1];
strcpy(array, temp);
}
void Link_Info::Load()
{
ifstream file_in; 
file_in.open("appt_info.txt");
if (file_in) 
{
Read_Pointer(link_name);
Read_Pointer(address);
Read_Pointer(description);
}
}

这就是我现在拥有的:

void Link_Info::Load()
{
ifstream file_in; 
file_in.open("appt_info.txt");
if (file_in) 
{
char temp[MAX]; 
file_in.get(temp, MAX, '~'); 
file_in.ignore(100, '~');
link_name = new char [ strlen(temp) + 1];
strcpy(link_name, temp);
file_in.get(temp, MAX, '~'); 
file_in.ignore(100, '~');
address = new char [ strlen(temp) + 1];
strcpy(address, temp);
file_in.get(temp, MAX, '~'); 
file_in.ignore(100, '~');
description = new char [ strlen(temp) + 1];
strcpy(description, temp);
file_in.get(temp, MAX, '~'); 
file_in.ignore(100, '~');
misc = new char [ strlen(temp) + 1];
strcpy(misc, temp);  

}
file_in.close();
}

看起来你真的很接近。以下是我会做的一些不同的事情:

// Define an exception to throw when the file cannot be read.
// If the file can't be read, you might as well pass the buck up the call 
// stack until it reaches a point that's capable of deciding what to do.
// This is a perfect time to use an exception 
class inv_file: public std::exception
{
public:
const char* what() const noexcept
{
return "unable to parse input file";
}
};
// Return the allocated string rather than passing it in.
// Passing in a pointer gets kinda tricky because while passing an object by pointer 
// is a form of pass by reference, the pointer itself is passed by value and won't 
// be updated if you change where it points inside the function. You have to pass the 
// pointer itself by reference. Just returning the pointer is less of a fuss.
char * Link_Info::Read_Pointer()
{    
char temp[MAX]; 
// always test for successful IO transaction. You do not want to use bad or 
// incomplete data. The world is littered with programs that crash and computers 
// enslaved by botmasters or otherwise twisted to the will of an attacker because 
// this simple rule was not followed.
if (file_in.get(temp, MAX, '~') &&
file_in.ignore(100, '~'))
{ // successfully read up to a ~ and then ignored to the next ~
// do what you did.
array = new char [ strlen(temp) + 1];
strcpy(array, temp);
return array; // and return the result
}
throw inv_file(); // did not read expected data so we report the failure 
// in a way that cannot be easily ignored 
}
void Link_Info::Load()
{
ifstream file_in; 
file_in.open("appt_info.txt");
if (file_in) 
{
link_name = Read_Pointer(); // accepts returned value. We don't have 
// to worry about garbage because the exception 
// thrown if the read failed is not caught.
// it stops this function dead and the caller 
// needs to deal with it or allow it to continue
// back up the call stack.
address = Read_Pointer();
description = Read_Pointer();
}
}