如何将这些字符串拆分为数组

时间:2010-11-30 20:26:55

标签: c++ split

我正在寻找一种方法将以下文本行拆分为数组。

  

这是一些文字\ r \ n“这里是另一行”\ r \ n和另一行

这样得到的数组是:

  

以下是一些文字

     

\ r \ n

     

     

这是另一行

     

     

\ r \ n

     

另一行

请注意,此处基本上有两个分隔符, \ r \ n
我需要在C ++中这样做,将来可能会有额外的分隔符 有什么想法吗?

提前致谢。

编辑:不,这不是作业。

这是我到目前为止所拥有的:

const RWCString crLF = "\r\n";
const RWCString doubleQuote = "\"";


    RWTValOrderedVector<RWCString> Split(const RWCString &value, const RWCString &specialContent)
    {
        RWTValOrderedVector<RWCString> result;

        unsigned index = 0;

        RWCString str = value;

        while ( ( index = str.index( specialContent, 0, RWCString::ignoreCase ) ) != RW_NPOS )
        {
            RWCString line = str(0, index);

            result.append(line);
            result.append(specialContent);

            str = str(index, str.length() - index);
            str = str(specialContent.length(), str.length() - specialContent.length());
        }

        if (str.length() > 0)
        {
            result.append(str);
        }

        return result;
    }

        void replaceSpecialContents(const RWCString &value)
        {

            RWTValOrderedVector<RWCString> allStrings;

            RWTValOrderedVector<RWCString> crLFStrings = Split(value, crLF);

            for (unsigned i=0; i<crLFStrings.entries(); i++)
            {
            RWTValOrderedVector<RWCString> dqStrings = Split(crLFStrings[i], doubleQuote);

                if (dqStrings.entries() == 1)
                {
                    allStrings.append(crLFStrings[i]);
                }
                else
                {
                    for (unsigned j=0; j<dqStrings.entries(); j++)
                    {
                        allStrings.append(dqStrings[j]);
                    }
                }
            }

    }

8 个答案:

答案 0 :(得分:2)

这是一种可以在C和C ++中使用的方法:

//String to tokenize:
char str[] = "let's get some tokens!";

//A set of delimiters:
char delims[] = " ";

//List of tokens:
char *tok1 = NULL,
     *tok2 = NULL,
     *tok3 = NULL;

//Tokenize the string:
tok1 = strtok(str, delims);
tok2 = strtok(NULL, delims); //after you get the first token
tok3 = strtok(NULL, delims); //supply "NULL" as first strtok parameter

你可以通过各种方式修改。您可以将所有“strtok(NULL,delims)”调用放在循环中以使其更灵活,您可以使用.c_str()等与C ++字符串接口。

答案 1 :(得分:1)

getline有一个可选的分隔符,因此您只需花费很少的精力即可使用stringstream来执行此分隔符。缺点是(我相信)它一次只能使用一个分隔符。

答案 2 :(得分:1)

将问题视为如下:

  1. 我有一个指向substring的指针。如何找到下一个子字符串?
  2. 我有一个指向substring的指针。如何将其添加为数组的下一个元素?
  3. 现在,解决1和2.如果有任何问题,请再次询问。

答案 3 :(得分:1)

您可以使用string::find_first_ofstring::substr。小心检查“空”字符串; find_first_of会找到char s,因此\r\n都会被生成的算法拆分。

或者,迭代整个字符串,并在遇到另一个分隔符时复制上一部分。

答案 4 :(得分:1)

一种非常简单的方法就是使用flex:
你可以在一些非常易读的行中为C ++应用程序构建一个非常简单的词法分析器。

注意:

我会注意到你应该小心'\ r \ n'。如果以文本模式(默认)打开文件,则标准流读取将标准行终止序列转换为'\ n'。在某些平台上,行终止序列的结尾为'\ r \ n',因此如果您从文件中读取流,则只能看到'\ n'字符。

split.lex

%option c++
%option noyywrap
%%
\"           return 1;
\r\n         return 2;
[^"\r\n]*    return 3;
%%

的main.cpp

#include "FlexLexer.h"

int main()
{
    yyFlexLexer     lexer(&std::cin, &std::cout);
    int             token;

    while((token = lexer.yylex()) != 0)
    {
        std::string  tok(lexer.YYText(), lexer.YYText() + lexer.YYLeng());
        std::cout << "Token: " << token << "(" << tok << ")\n";
    }
}

构建

% flex split.lex
% g++ main.cpp lex.yy.cc

运行(在预先准备的文件上)

% cat testfile | ./a.exe
Token: 3(Here is some text)
Token: 2(
)
Token: 1(")
Token: 3(here is another line)
Token: 1(")
Token: 2(
)
Token: 3(And another line)

答案 5 :(得分:1)

在您正在使用的Rogue Wave SourcePro API的基础上,您可以使用RWTRegex将字符串拆分为标记:

RWTValOrderedVector<RWCString> tokenize(const RWCString& str)
{
    RWTRegex<char> re("\\r\\n|\"|([^\"\\r]|\\r[^\\n])*|\\r$");

    RWTRegex<char>::iterator it(re, str);

    RWTValOrderedVector<RWCString> result;
    for (; it != RWTRegex<char>::iterator(); ++it) {
        result.append(it->subString(str));
    }
    return result;
}

有关RWTRegex的详细信息,请参阅http://www.roguewave.com/Portals/0/products/sourcepro/docs/12.0/html/sourceproref/classRWTRegex.html

答案 6 :(得分:0)

这是一种使用TR1正则表达式功能的方法。

std::string text("Here is some text\r\n\"here is another line\"\r\nAnd another line");
std::vector<std::string> vec;

std::regex rx("[\\w ]+|\\r\\n|\"");
std::sregex_iterator rxi(text.begin(), text.end(), rx), rxend;

for (; rxi != rxend; ++rxi)
{
    vec.push_back(rxi->str());
}

在我的测试中,这会在您的示例中使用7个子字符串填充向量。我不是专家,所以可能有一个比我正在使用的更正确的正则表达式。

答案 7 :(得分:0)

strtok会用NULL替换你的令牌。这就是为什么它不包括令牌。

man strtok获取更多信息。我也在使用strtok和strtok_r,因为我有以下

的传入char数组

你好~Milktea~这是我的留言\ r \ n消息〜我看了很好〜卡地亚\ r \ n

我将首先剥离〜(波浪线),然后是\ r \ n,反之亦然。

相关问题