微軟面試題實現一個strtok函數

strtok的描述在這裏http://www.cplusplus.com/reference/cstring/strtok/

char * strtok ( char * str, const char * delimiters );

 

Split string into tokens

 

A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.



On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of the last token as the new starting location for scanning.



To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token. The scan also stops if the terminating null character is found.



This end of the token is automatically replaced by a null-character, and the beginning of the token is returned by the function.

Once the terminating null character of str is found in a call to strtok, all subsequent calls to this function (with a null pointer as the first argument) return a null pointer.

The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).





/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

 

這個函數還是有些難度,在中文社區幾乎找不到滿意的答案,用bin在英文社區搜索,去stackoverflow找到答案,首先用一個簡單的例子描述這個算法:

char s[] = "this is a string";

in the above string space seems to be a good delimiter between words so lets use that:

char* p = strtok(s, " ");

what happens now is that 's' is searched until the space character is found, the first token is returned ('this') and p points to that token (string)

in order to get next token and to continue with the same string NULL is passed as first argument since strtok maintains a static pointer to your previous passed string:

p = strtok(NULL," ");

爲什麼這裏要傳NULL,因爲原來的str會被改變,爲了方便,函數內部會在第一次調用的時候維護一個靜態變量去記錄字符串指針位置。

p now points to 'is'

and so on until no more spaces can be found, then the last string is returned as the last token 'string'.

more conveniently you could write it like this instead to print out all tokens:

for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " "))
{
  puts(p);
}
  • Create a function strtok() which accepts string and delimiter as an argument and return char pointer.
  • Create a static variable input to maintain the state of the string.
  • Check if extracting the tokens for the first time then initialize the input with it.
  • If the input is NULL and all the tokens are extracted then return NULL.
  • In this step, start extracting tokens and store them in the array result[].
  • Now, iterate a loop until NULL occurs or the delimiter then return the result by including ‘\0’.
  • When the end of the string is reached and if it requires then manually add a ‘\0‘ and include this corner case in the end.

這是一個簡單實現:

char* mystrtok(char* s, char d) 
{ 
    // Stores the state of string 
    static char* input = NULL; 
  
    // Initialize the input string 
    if (s != NULL) 
        input = s; 
  
    // Case for final token 
    if (input == NULL) 
        return NULL; 
  
    // Stores the extracted string 
    char* result = new char[strlen(input) + 1]; 
    int i = 0; 
  
    // Start extracting string and 
    // store it in array 
    for (; input[i] != '\0'; i++) { 
  
        // If delimeter is not reached 
        // then add the current character 
        // to result[i] 
        if (input[i] != d) 
            result[i] = input[i]; 
  
        // Else store the string formed 
        else { 
            result[i] = '\0'; 
            input = input + i + 1; 
            return result; 
        } 
    } 
  
    // Case when loop ends 
    result[i] = '\0'; 
    input = NULL; 
  
    // Return the resultant pointer 
    // to the string 
    return result; 
} 
  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章