逐行将1和0的文件加载到char **中

时间:2015-12-02 21:04:34

标签: c++ arrays file char istream

我有一个文件,在每行的末尾可能有换行符:

111\n
100\n
101

1 个答案:

答案 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>标题getlinestd::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