2017-04-13 155 views
-1

我想知道這是否是將字符串分解爲特定變量的安全方式。我目前沒有得到正確的結果。需要newFirstName來包含Joe。 newLast名稱包含Robbin。 NewTeam包含油工等等。我目前得到的是除了newFirstname之外的所有變量。正確方向的一點將不勝感激。如何用特定分隔符分隔字符串?

string line = "Joe|Robbin|Oilers|34|23"; 
    char* strToChar = NULL; 
    char* strPtr = NULL; 

    string newFirstName = " "; 
    string newLastName = " "; 
    string newTeam = " "; 
    int newAssists = 0; 
    int newGoals = 0; 

    sscanf(line.c_str(), "%[^|]s%[^|]s%[^|]s%d|%d",(char*)newFirstName.c_str(), (char*)newLastName.c_str(), (char*)newTeam.c_str(), &newGoals, &newAssists); 

看到許多偉大的答案,但我做之前,我想出了:

string line = "Joe|Robbin|Oilers|34|23"; 
    char* strToChar = NULL; 
    char* strPtr = NULL; 
    string newFirstName = " "; 
    string newLastName = " "; 
    string newTeam = " "; 
    int newAssists = 0; 
    int newGoals = 0; 
    int count = 0; 



    std::string delimiter = "|"; 

    size_t pos = 0; 
    std::string token; 
    while ((pos = line.find(delimiter)) != std::string::npos) 
    { 
     count++; 
     token = line.substr(0, pos); 
     std::cout << token << std::endl; 
     line.erase(0, pos + delimiter.length()); 

     switch (count) 
     { 
     case 1: 
      newFirstName = token; 
      break; 
     case 2: 
      newLastName = token; 
      break; 
     case 3: 
      newTeam = token; 
      break; 
     case 4: 
      newGoals = atoi(token.c_str()); 
      break; 
     } 


    } 
    newAssists = atoi(line.c_str()); 
+1

您不能分配到'.c_str()'這種方式。字符串沒有足夠的空間分配給您放入它們的字符串。 – Barmar

+0

*我想知道這是否是將字符串分解成特定變量的安全方式* - 快速回答 - 不可以。停止使用強制轉換,並停止使用「C」。 – PaulMcKenzie

+0

爲什麼'std :: string :: c_str()'返回const char *'有一個原因 - 你不能直接修改字符串。 – Barmar

回答

1

要分隔符以外的空間被一些分裂的字符串,最簡單的就是一個stringstream隨着std::getline使用,它允許指定你的分隔字符。

std::istringstream iss(line); 
std::getline(iss, newFirstName, '|'); 
std::getline(iss, newLastName, '|'); 
std::getline(iss, newTeam, '|'); 
iss >> newAssists; 
iss.ignore(); // drop the '|' 
iss >> newGoals; 

你這樣做的方式有很多問題在評論中指出。最重要的錯誤是試圖通過sscanf直接寫入std :: string的緩衝區,這破壞了數據封裝的最重要規則並導致未定義的行爲。

1

我想知道這是否是將字符串拆分爲特定變量的安全方法。

我的建議:

  1. 使用std::istringstreamstd::getline來標記線。
  2. 使用std::stoi拉出令牌中的數字。

下面是一個工作示例。

#include <iostream> 
#include <sstream> 
#include <string> 

int main() 
{ 
    std::string line = "Joe|Robbin|Oilers|34|23"; 
    std::istringstream str(line); 

    std::string newFirstName; 
    std::string newLastName; 
    std::string newTeam; 
    std::string newAssistsString; 
    std::string newGoalsString; 

    std::getline(str, newFirstName, '|'); 
    std::getline(str, newLastName, '|'); 
    std::getline(str, newTeam, '|'); 
    std::getline(str, newAssistsString, '|'); 
    std::getline(str, newGoalsString); 

    // Sanity check. 
    if (!str) 
    { 
     std::cout << "Unable to extract the tokens from the line\n"; 
     return EXIT_FAILURE; 
    } 

    int newAssists = std::stoi(newAssistsString); 
    int newGoals = std::stoi(newGoalsString); 

    std::cout 
     << newFirstName << " " 
     << newLastName << " " 
     << newTeam << " " 
     << newAssists << " " 
     << newGoals << std::endl; 

    return EXIT_SUCCESS; 
} 

輸出

Joe Robbin Oilers 34 23