我有一个文件,在每行的末尾可能有换行符:
111\n
100\n
101
答案 0 :(得分:2)
在C ++中,您可以将文件行加载到字节字符串数组中,如下所示:
auto lines_from( istream& is )
-> vector<string>
{
string line;
vector<string> result;
while( getline( is, line ) )
{
result.push_back( line );
}
return result;
}
auto main() -> int
{
vector<string> const lines = lines_from( cin );
// Use it.
}
此string
std::string
来自<string>
标题getline
,std::getline
vector
来自同一标头,std::vector
为{{1}来自<vector>
标题。我选择使用函数的描述性名称lines_from
。但是,它通常被命名为readall
。
如果您绝对需要char**
,可能假设每个字符串都有一些给定的缓冲区大小,那么您可以使用指针向量,指向缓冲区,例如由这样的类管理:
class C_strings
{
private:
vector<string> buffers_;
vector<char*> pointers_;
int bufsize_;
C_strings( C_strings const& ) = delete;
auto operator=( C_strings const& ) -> C_strings& = delete;
public:
auto pointer() -> char** { return pointers_.data(); }
auto bufsize() const -> int { return bufsize_; }
C_strings( vector<string> const& strings, int const bufsize )
: buffers_( strings )
, bufsize_( bufsize )
{
pointers_.reserve( buffers_.size() + 1 );
for( string& s : buffers_ )
{
s.reserve( bufsize );
if( s.empty() or s.back() != '\0' ) { s += '\0'; }
pointers_.push_back( &s[0] );
}
pointers_.push_back( nullptr );
}
C_strings( C_strings&& other )
: buffers_( move( other.buffers_ ) )
, pointers_( move( other.pointers_ ) )
{}
};
然后让我们说你要打这样的双星函数:
void doublestarfunc( char** const lines )
{
using std::cout;
for( char** pps = lines; *pps != nullptr; ++pps )
{
if( strlen( *pps ) < 40 ) { strcat( *pps, " < Oh la la!" ); }
cout << *pps << '\n';
}
cout << '\n';
}
可以非常简单地完成:
using namespace std; // cin, cout
int const columns = 80;
int const cstring_bufsize = columns + 1;
auto c_strings = C_strings( lines_from( cin ), cstring_bufsize );
doublestarfunc( c_strings.pointer() );
但这是个好主意吗?不,除非您必须与现有的C样式API相关。对于C ++代码,更好地重构它以在整个过程中使用C ++ std::string
。