std :: string操作:空格,"newline escapes'\'"和注释#

rub*_*nvb 1 c++ string algorithm

有点在这里寻求肯定.我有一些手工编写的代码,我并不害羞地说我很自豪,它会读取文件,删除前导空格,处理换行符'\'并删除以#开头的注释.它还会删除所有空行(也是仅空白行).有什么想法/建议?我可以用std :: runtime_errors替换一些std :: cout ......但这不是优先考虑的事:)

const int RecipeReader::readRecipe()
{
    ifstream is_recipe(s_buffer.c_str());
    if (!is_recipe)
        cout << "unable to open file" << endl;
    while (getline(is_recipe, s_buffer))
    {
        // whitespace+comment
        removeLeadingWhitespace(s_buffer);
        processComment(s_buffer);
        // newline escapes + append all subsequent lines with '\'
        processNewlineEscapes(s_buffer, is_recipe);
        // store the real text line
        if (!s_buffer.empty())
            v_s_recipe.push_back(s_buffer);
        s_buffer.clear();
    }
    is_recipe.close();
    return 0;
}

void RecipeReader::processNewlineEscapes(string &s_string, ifstream &is_stream)
{
    string s_temp;
    size_t sz_index = s_string.find_first_of("\\");
    while (sz_index <= s_string.length())
    {
        if (getline(is_stream,s_temp))
        {
            removeLeadingWhitespace(s_temp);
            processComment(s_temp);
            s_string = s_string.substr(0,sz_index-1) + " " + s_temp;
        }
        else
            cout << "Error: newline escape '\' found at EOF" << endl;
        sz_index = s_string.find_first_of("\\");
    }
}

void RecipeReader::processComment(string &s_string)
{
    size_t sz_index = s_string.find_first_of("#");
    s_string = s_string.substr(0,sz_index);
}

void RecipeReader::removeLeadingWhitespace(string &s_string)
{
    const size_t sz_length = s_string.size();
    size_t sz_index = s_string.find_first_not_of(" \t");
    if (sz_index <= sz_length)
    s_string = s_string.substr(sz_index);
    else if ((sz_index > sz_length) && (sz_length != 0)) // "empty" lines with only whitespace
        s_string.clear();
}
Run Code Online (Sandbox Code Playgroud)

一些额外的信息:传递给ifstream的第一个RRRuffer包含文件名,std :: stringprouffer是一个类数据成员,因此是std :: vector v_s_recipe.欢迎任何评论:)

更新:为了不忘恩,这里是我的替代,一体化功能,我现在想做的事情(未来持有:括号,可能是引号......):

void readRecipe(const std::string &filename)
{
    string buffer;
    string line;
    size_t index;
    ifstream file(filename.c_str());
    if (!file)
        throw runtime_error("Unable to open file.");

    while (getline(file, line))
    {
        // whitespace removal
        line.erase(0, line.find_first_not_of(" \t\r\n\v\f"));
        // comment removal TODO: store these for later output
        index = line.find_first_of("#");
        if (index != string::npos)
            line.erase(index, string::npos);
        // ignore empty buffer
        if (line.empty())
            continue;
        // process newline escapes
        index = line.find_first_of("\\");
        if (index != string::npos)
        {
            line.erase(index,string::npos); // ignore everything after '\'
            buffer += line;
            continue; // read next line
        }
        else // no newline escapes found
        {
            buffer += line;
            recipe.push_back(buffer);
            buffer.clear();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Soa*_*Box 9

绝对放弃匈牙利的符号.

  • "is_"前缀特别不幸. (3认同)
  • 我没有花时间对此发表评论,但Joel Spolsky撰写了一篇关于匈牙利乐谱的非常好的文章以及它是如何被歪曲的.你在这里使用的表格是变态的:表示变量的类型是多余的,并没有带来任何表格.如果您想阅读更多内容,我只能推荐Joel的文章http://www.joelonsoftware.com/articles/Wrong.html.和Joel一样,它有点冗长,你可以使用浏览器的搜索功能来达到目的;) (2认同)

Bil*_*eal 6

这还不错,但我认为你想的std::basic_string<T>是一个字符串而不是STL容器.例如:

void RecipeReader::removeLeadingWhitespace(string &s_string)
{
    s_string.erase(s_string.begin(), 
        std::find_if(s_string.begin(), s_string.end(), std::not1(isspace)));
}
Run Code Online (Sandbox Code Playgroud)