请考虑以下此类模板的代码片段...
template<class T>
class FileTemplate {
private:
std::vector<T> vals_;
std::string filenameAndPath_;
public:
inline FileTemplate( const std::string& filenameAndPath, const T& multiplier ) :
filenameAndPath_( filenameAndPath ) {
std::fstream file;
if ( !filenameAndPath_.empty() ) {
file.open( filenameAndPath_ );
T val = 0;
while ( file >> val ) {
vals_.push_back( val );
}
file.close();
for ( unsigned i = 0; i < vals_.size(); i++ ) {
vals_[i] *= multiplier;
}
file.open( filenameAndPath_ );
for ( unsigned i = 0; i < vals_.size(); i++ ) {
file << vals_[i] << " ";
}
file.close();
}
}
inline std::vector<T> getValues() const {
return vals_;
}
};
当在main中使用时,下部用以下预先填充的文本文件注释掉:
values.txt
1 2 3 4 5 6 7 8 9
int main() {
std::string filenameAndPath( "_build/values.txt" );
std::fstream file;
FileTemplate<unsigned> ft( filenameAndPath, 5 );
std::vector<unsigned> results = ft.getValues();
for ( auto r : results ) {
std::cout << r << " ";
}
std::cout << std::endl;
/*
FileTemplate<float> ft2( filenameAndPath, 2.5f );
std::vector<float> results2 = ft2.getValues();
for ( auto r : results2 ) {
std::cout << r << " ";
}
std::cout << std::endl;
*/
std::cout << "\nPress any key and enter to quit." << std::endl;
char q;
std::cin >> q;
return 0;
}
我通过调试器运行此代码,确保将屏幕和文件的输出都更改为
values.txt - 覆盖 -
5 10 15 20 25 30 35 40 45
然后让我说我不改变任何代码只是停止调试或运行应用程序,让我们说我再次运行2次,输出分别是:
values.txt - 迭代2和3
25 50 75 100 125 150 175 200 225 250
125 250 375 500 625 750 875 1000 1125 1250
好的,到目前为止;现在让我们将文本文件中的值重置为默认值,并允许取消注释具有乘数值2.5f的浮点数的此类模板的第二个实例,然后运行3次。
values.txt - 重置为默认值
1 2 3 4 5 6 7 8 9
-iterations 1,2&3,无符号和浮点数乘数分别为<5,2.5>。 5表示无符号,2.5表示浮点数
- Iteration 1费用:
5 10 15 20 25 30 35 40 45 12.5 25 37.5 50 62.5 75 87.5 100 112.5
values.txt:
12.5 25 37.5 50 62.5 75 87.5 100 112.5
- Iteration 2费用:
60 150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25
values.txt:
150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25
- Iteration 3费用:
750 60 1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125
values.txt:
1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125
我想到了几个问题:关于这个程序的相同行为,它有两个问题。
第一个和主要的问题是:文件读取和写入调用是否在编译时完成,考虑到这是一个类模板,构造函数是内联的?
运行调试器几次后;为什么输出会增加文件中的值的数量?我从9开始,但经过一次迭代后,有10个,然后是11个。
这部分只是为了好玩,如果你想回答:
第三个也是最后一个问题是基于意见,但仅仅是出于教育目的,我希望看到社区对此有何看法:这类编程的优缺点是什么?有什么潜力和极限?他们的实际应用和生产是否有益于此?
就其他问题而言。主要问题是当你执行第二个file.open
语句时,你没有截断文件,你需要:
file.open( filenameAndPath_, std::fstream::trunc|std::fstream::out );
发生的事情是,当你从包含浮点的文件中读取unsigned int
时,它只读取第一个数字(例如12.5)直到小数位然后停止(例如只读取12个),因为没有其他在看起来像unsigned int
的线上的文字。这意味着它只读取数字12,然后将其乘以5得到60,并将其写入文件。
不幸的是,因为在写入60时没有截断文件,所以它会在原始文本末尾留下原始文本,在下一个读取循环中将其解释为附加数字。因此,12.5
在文件中显示为60 5
stream buffers从流中提取尽可能多的字符,并将它们插入由sb指向的流缓冲区对象(如果有)控制的输出序列中,直到输入序列耗尽或函数无法插入到指向的对象中SB。
(Qazxswpoi)