2017-03-28 18 views
1

私はこのソフトウェアを作成しています。私はちょうどスクリプトを入れて、スパンで私のコードを強調表示します。そこに着いていますが、私には問題があります。 (私は現在UnityC#のハイライトに取り組んでいます)C++ - 文字列を二重引用符で囲んだ文字列に置き換えます。

二重引用符を含めて文字列を黄色にしたいのですが、私が今試している方法では無限ループが発生します。私は引用符で間違って何かをしていることを知っているが、私はそれが何であるか把握することはできません。私を助けてください:)

変数元は私が

std::size_t pos = 0; 
while(original.find("\"", pos) != std::string::npos) 
{ 
    //find the first occurrence of the quote 
    std::size_t found = original.find("\"", pos); 
    if(found != std::string::npos) 
    { 
     //save the start position of the string 
     std::size_t start_pos = found; 
     //save the end position by searching for the next quotation mark 
     std::size_t end_pos = original.find_first_of("\"", start_pos+1); 
     //Calculate the size of the string 
     std::size_t length = end_pos-start_pos; 
     //Make a copy of the word without the quotation marks 
     std::string originalWord = original.substr(start_pos+1, length-1); 
     //Make the new word with span, original word(without the quotation marks) and add quotation marks around the word 
     std::string newWord = std::string("<span class='yellow_code'>") + "\"" + originalWord + "\"" + "</span>"; 
     std::cout<<originalWord<<" : "<<newWord<<std::endl; 
     //Replace the string WITH the quotation marks for the newWord 
     original.replace(start_pos, length+1, newWord); 
     //Set the position to after the string 
     pos = end_pos+1; 
    } 
    else 
    { 
     pos = found+1; 
    } 
} 

にロードするスクリプト私はこれを実行すると、それはCOUTますですcurrentFilestd::string original ((istreambuf_iterator<char>(currentFile)), istreambuf_iterator<char>());、によって作成された

:/dataValues.dat:<スパンクラス= 'yellow_code' > "/dataValues.dat" </span >無限大です。

どうしたのですか?

よろしく、 ダニ

+1

を試してみてください。これはあなたのためにこれを非常に簡単に行います。 –

+1

私の古い教授は、「引用文字」と呼ばれることを主張していました。見積もりは動詞で、名詞ではありません;-) – Bathsheba

+0

あなたに例を挙げてもらえますか? – Shravan40

答えて

3

は、問題はここにある:文字列は、それはあなたのプリアンブルよりも短いことである前に、あなたのインデックスをさせることができますpos = end_pos + 1;

私たちはあなたの例で何が起こるか見てみましょう:

  • もともとoriginalbla..."/dataValues.dat"...end_posであるあなたはbla...<span class='yellow_code'>"/dataValues.dat"</span>...end_posが黄色の最初のlに変更し、ポイントされていません取得、交換後pos + 16
  • されます!あなたは再び同じ引用符で囲まれた文字列を見つける次の検索に
  • ...

あなたはそれはあなたがサイズを追加していないすぐに</span>

+0

ありがとう、私はダム感じた – danivdwerf

0

あなた必要がありますstd::regex

text = std::regex_replace(text,std::regex("string to be replaced"),"string with it earlier should be replaced"); 
+0

私は答えを感謝しますが、もう一つは実際に私にいくつかのビルドを使用するように指示するのではなく、私の質問に答えました。 – danivdwerf

2

後にポイントにするためにend_pos<span...></span>の長さを追加する必要があります文字列に追加する開始タグと終了タグのここ は、あなたがそれを彼ら二人が冗長だったようにそれが見えた

std::string start_tag = "<span class='yellow_code'>"; 
std::string end_tag = "\"</span>"; 

std::size_t pos = 0; 
while(original.find("\"", pos) != std::string::npos) 
{ 
    std::size_t found = original.find("\"", pos); 
    if(found != std::string::npos) 
    { 
     std::size_t start_pos = found; 
     std::size_t end_pos = original.find_first_of("\"", start_pos+1); 
     if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior 
      break; 
     std::size_t length = end_pos - start_pos; 
     std::string originalWord = original.substr(start_pos+1, length-1); 
     std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string 
     std::cout<<originalWord<<" : "<<newWord<<std::endl; 
     original.replace(start_pos, length+1, newWord); 
     pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags 
    } 
} 

UPDATE

posを見た後

found、およびstart_posを行うことができる方法の一例です。

std::size_t start_pos = 0; 
while((start_pos = original.find("\"", start_pos)) != std::string::npos) 
{ 
    std::size_t end_pos = original.find_first_of("\"", start_pos+1); 
    if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior 
     break; 
    std::size_t length = end_pos-start_pos; 
    std::string originalWord = original.substr(start_pos+1, length-1); 
    std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string 
    std::cout << originalWord << " : " << newWord <<std::endl; 
    original.replace(start_pos, length+1, newWord); 
    start_pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags 
} 

あなたが `のstd :: regex`を使用することを検討して、C++ 11の使用を許可している場合、それをonline

+0

私はダム、多くの感謝 – danivdwerf

+1

@ danivdwerfあなたの質問にupvotesの数を見て、あなたの問題は、トピック、本当に面白かったことは明らかです。だから本質的に、ばかではない! – Jonas

関連する問題