2011-10-10 45 views
0

我有一定的字符串處理的事情,我現在用的方法是下面的示例中 -字符串處理和內存管理C++

Void ProcessObjects(int nObject) 
{ 
    std::string sInfostr; 

    for(int i = 0;i<nObject;i++) 
    { 
     InfoObject Inf = new InfoObject; 
     GetInfoObject(&Inf); 
     GetStoredInformation(Inf, std::string &sInfostr) 
     delete Inf;   
    } 
} 


void GetStoredInformation(InfoObject Inf, std::string &sInfostr) 
{ 
    char tag[1000]; 

    GetInformation(&Inf); 

    sprintf(tag, "name=%s",Inf.name); 
    sInfostr += tag;   
    sprintf(tag, "name1=%s",Inf.name1); 
    sInfostr += tag; 
    sprintf(tag, "name2=%s",Inf.name2); 
    sInfostr += tag; 
    sprintf(tag, "name3=%s",Inf.name3); 
    sInfostr += tag; 
    sprintf(tag, "name4=%s",Inf.name4); 
} 

現在,我可以得到一些建議是它來處理字符串的好辦法? 如果「nObject」高於10,000,我會不會遇到任何麻煩?

+2

爲什麼'InfoObject'的GetInfObject()和GetStoredInformation()方法? – trojanfoe

+1

爲什麼不聲明'name','name1' ....'name4'全部爲'std :: string'? – Nawaz

+0

「我使用的方法在下面的示例中」。不它不是。這段代碼充斥着語法錯誤。請發佈一個工作示例。 – Johnsyweb

回答

1

我建議你使用std::istringstream而不是舊的C-ISH sprintf

void GetStoredInformation(InfoObject Inf, std::string &sInfostr) 
{ 
    GetInformation(&Inf); 
    std::istringstream stream(); 
    stream << "name=" << Inf.name 
      << "name1=" << Inf.name1 
      << "name2=" << Inf.name2 
      << "name3=" << Inf.name3 
      << "name4=" << Inf.name4; 
    sInfostr = stream.str(); 
} 

我會去編寫任何麻煩,如果 「n對象」 超過10,000?

取決於所使用的硬件,從它不應該是一個問題,除非你的InfoObject不是非常大的C++點。

+0

'std :: istringstream stream();'很煩人...... – visitor

1

你的代碼很粗略,包含幾個語法錯誤,可能是內存泄漏。

關於您的實際問題,建議使用std::stringstream建立字符串。它應該是這樣的:

std::stringstream buffer; 
buffer << "name=" << Inf.name 
    << "name1=" << Inf.name1; // etc. 

您可以訪問緩衝區的內容作爲std::string使用buffer.str()

除了更優雅,這可能也更快,因爲std::stringstream使用比的operator +=更智能的分配策略。

+0

你確定。上一次我測量(前一段時間),我使用'std :: ostringstream'的實現最終只是在'std :: string'上執行'+ ='。在這種特殊情況下(只是追加字符串),'std :: string'會更簡單和更快速。 (使用'ostringstream',當然,如果你必須轉換任何東西。) –

+0

@詹姆斯:說實話,我不確定,因爲我沒有測量。 –

1

如果聲明namename1 .... name4所有爲std::string,那麼你就簡單的寫:

sInfostr = "name = " + Inf.name 
     + "name1 = " + Inf.name1 
     + "name2 = " + Inf.name2 
     + "name3 = " + Inf.name3 
     + "name4 = " + Inf.name4; 

這是非常巧妙的解決方案,因爲它更容易閱讀和維護。

您可以添加成員函數調用ToString()InfoObject類爲:

class InfoObject 
{ 
    //... 
    std::string ToString() const 
    { 
    return = "name = " + Inf.name 
      + "name1 = " + Inf.name1 
      + "name2 = " + Inf.name2 
      + "name3 = " + Inf.name3 
      + "name4 = " + Inf.name4; 
    } 
}; 

然後GetStoredInformation將只是兩行:

void GetStoredInformation(InfoObject Inf, std::string &sInfostr) 
{ 
    GetInformation(&Inf); 
    sInfostr = Inf.ToString(); 
} 

更妙的是,如果你做GetStoredInformation的成員函數InfoObject

0

根本不應該使用sprintf。正如你懷疑的那樣,這是不安全的。如果任何Inf.name*字符串的長度超過1000個字符,則會損壞可能導致崩潰或更糟糕的堆棧,這是通過代碼注入造成的安全漏洞。

您的格式字符串足夠簡單;解決方案應該更像,

void GetStoredInformation(InfoObject Inf, std::string &sInfostr) 
{ 
    GetInformation(&Inf); 
    sInfostr += "name=";// did you mean sInfostr = "name"? 
    sInfostr += Inf.name; 
    sInfostr += "name1="; 
    sInfostr += Inf.name1; 
    sInfostr += "name2="; 
    sInfostr += Inf.name2; 
    sInfostr += "name3="; 
    sInfostr += Inf.name3; 
    sInfostr += "name4="; 
    sInfostr += Inf.name4; 
}