2010-02-07 53 views
2

我從編輯框中獲取文本,並希望通過輸入鍵分隔每個名稱,如下面的字符串與空字符一樣。在輸入鍵中分割字符串

char *names = "Name1\0Name2\0Name3\0Name4\0Name5"; 

    while(*names) 
    { 
     names += strlen(names)+1; 
    } 

你會如何做相同的輸入密鑰(即分隔/ r/n)?你可以做到這一點,而不使用std :: string類嗎?

+0

你需要額外的\ 0在你的字符串末尾或你的while將跑離你的字符串的結尾。 '「.... \ 0Name5 \ 0」' – 2010-02-07 06:35:02

+0

@John Knoeller:當我意識到OP在談論換行符而不是空字符時,我正要發表該評論。 '\ 0'作爲他試圖剔除的分隔符的一個例子。 – dirkgently 2010-02-07 06:41:15

回答

2

使用的strstr:

while (*names) 
{ 
    char *next = strstr(names, "\r\n"); 
    if (next != NULL) 
    { 
     // If you want to use the key, the length is 
     size_t len = next - names; 

     // do something with a string here. The string is not 0 terminated 
     // so you need to use only 'len' bytes. How you do this depends on 
     // your need. 

     // Have names point to the first character after the \r\n 
     names = next + 2; 
    } 
    else 
    { 
     // do something with name here. This version is 0 terminated 
     // so it's easy to use 

     // Have names point to the terminating \0 
     names += strlen(names); 
    } 
} 

有一點需要注意的是,這種代碼也修復了你的代碼中的錯誤。你的字符串被一個\ 0結尾,因此最後一次迭代的名字將指向你的字符串之後的第一個字節。要解決現有的代碼,你需要在名稱的值更改爲:

// The algorithm needs two \0's at the end (one so the final 
// strlen will work and the second so that the while loop will 
// terminate). Add one explicitly and allow the compiler to 
// add a second one. 
char *names = "Name1\0Name2\0Name3\0Name4\0Name5\0"; 
+0

但你會在哪裏捕獲每個分隔的字符串名稱? – cpx 2010-02-07 06:49:26

+0

@ Dave17 - 你是什麼意思「catch」?您可以在if或else塊的最開始處使用該字符串。在第一個塊中,字符串不是0結尾,但你知道len。 – 2010-02-07 07:01:32

+0

我的意思是像每個'名稱'(Name1,Name2 ..)添加到數組或std ::列表。就像在'/ 0'的情況下,我可以使用*指向下一個的名字。 – cpx 2010-02-07 07:04:38

0

如果要開頭和C字符串結束,它不是真正的C++。

這是strsep的工作。

#include <stdlib.h> 
void split_string(char *multiline) { 
    do strsep(&multiline, "\r\n"); 
    while (multiline); 
} 

每次調用strsep零出無論是\r\n。由於只有字符串\r\n出現,所有其他呼叫都會返回參數。如果你願意,你可以通過記錄multiline來創建char*的數組,因爲它前進或返回值爲strsep

void split_string(char *multiline) { 
    vector< char* > args; 
    do { 
     char *arg = strsep(&multiline, "\r\n"); 
     if (* arg != 0) { 
      args.push_back(arg); 
     } 
    } while (multiline); 
} 

這第二個例子至少不是特定於Windows。

+0

@Samuel:是的,我考慮了這兩件事情。第一個片段的解釋說,每個其他'strsep'都會返回一個子字符串。第二個片段刪除\ r \ n's生成的空子串。 – Potatoswatter 2010-02-07 07:33:10

0

這裏是一個純粹的指針解決

char * names = "name1\r\nName2\r\nName3"; 
    char * plast = names; 

    while (*names) 
     { 
     if (names[0] == '\r' && names[1] == '\n') 
     { 
     if (plast < names) 
      { 
      size_t cch = names - plast; 
      // plast points to a name of length cch, not null terminated. 
      // to extract the name use 
      // strncpy(pout, plast, cch); 
      // pout[cch] = '\0'; 
      } 
     plast = names+2; 
     } 
     ++names; 
     } 

    // plast now points to the start of the last name, it is null terminated. 
    // extract it with 
    // strcpy(pout, plast); 
0

因爲這有C++標籤,最簡單的可能會使用C++標準庫,尤其是字符串和字符串流。爲什麼你想在C++中避免std::string

std::istringstream iss(names); 
std::string line; 
while(std::getline(iss,line)) 
    process(line); // do process(line.c_str()) instead if you need to