2012-03-09 92 views
2

提取的話我是相當新的C,因此遇到比較嚴重的混亂與使用指針。c - 從中​​字符串

我試圖從ASCII字符的字符串中提取的話。 例如,如果我有字符串@@ Hello..world >>,我想從字符串中獲得單詞「Hello」和「world」,並將它們添加到我的鏈接列表中。

一個字被定義爲任何字母序列,並且每個字至多爲64個字節。此外,函數isspace()返回一個非零值的任何字符都被認爲是空白。

基本上,我使用fscanf從文件中掃描字符串,然後爲每個調用我的函數的字符串read_words(char * s)從字符串中獲取正確的單詞並將它們添加到我的鏈接列表中以供進一步使用。

這裏是我的代碼,這似乎是扔有一個指針做一個錯誤。

struct node { 
    char *val; 
    struct node *next; 
    int count; 
} *words = NULL; 


void read_words(char *s) 
{ 
    struct node *tmp; 
    char word[64+1]; 
    int i, check, wordStarted = 0, count = 0; 

    for (i = 0; s[i] != '\0'; i++) 
    { 
      if ((isspace(s[i]) != 0) || !isalpha(s[i])) 
      { 
        if (wordStarted == 1) 
        { 
          check = check_list(word); 
          if (check != 1) { 
            word[count] = '\0'; 
            tmp = malloc(sizeof(struct node)); 
            tmp->val = word; 
            tmp->count = 1; 
            tmp->next = words; 
            words = tmp; 
          } 
          count = 0; 
          wordStarted = 0; 
        } 
      } 
      else 
      { 
        word[count++] = s[i]; 
        wordStarted = 1; 
      } 
    } 

} 

任何幫助,將不勝感激!

謝謝!

+0

嘗試'strtok'。它根據任意數量的拆分字符將字符串拆分爲多個部分。 – chris 2012-03-09 05:44:26

+0

您是否試過[調試](http://en.wikipedia.org/wiki/GNU_Debugger)您的代碼? – Zeta 2012-03-09 05:45:23

+0

請發表您的check_list()實現 – 2012-03-09 05:48:19

回答

3

您將要來標記字符串,而不是實現自己的算法和部分追加到鏈表。使用strtokref)。

從上面的鏈接..例如:

​​

輸出:

Splitting string "- This, a sample string." into tokens: 
This 
a 
sample 
string 
0

爲ANSI C.

用法strtok的更好的解決方案()它並不總是好:

  1. 它會改變原點數組。
  2. 空格分隔符「」忽略類似字符:「\ n」,「\ t」等。

嘗試下一個和閱讀評論的細節:

#include <stdio.h>  // printf 
#include <string.h>  // strlen, strncpy 
#include <ctype.h>  // isalnum 
#include <stdlib.h>  // malloc, calloc 

/* 
    A logical type 
*/ 
typedef enum { 
    false, 
    true, 
} bool; 


/* 
    A Struct for hold 2D-array with count items 
*/ 
typedef struct _ListWithLength { 
    char **list; 
    size_t length; 
} ListWithLength; 


/* 
    Parse a text and return pointer to a ListWithLength words and count it 
*/ 
ListWithLength* getWords(char *text) { 

    // a variable for count words 
    int count = 0; 

    // keep length of the text 
    size_t text_len = strlen(text); 

    // a flag indicating the a beginning of a word 
    bool new_word = false; 

    // an index of a start found a word 
    int index_start_word = 0; 

    // 2D-array for found word 
    // it will be same memory size as the original text 
    char **words = malloc(text_len * sizeof(char)); 

    for (int i = 0; i <= text_len; ++i) { 

     // if found ascii letter or digits and new no traced early 
     // keep index of beginning a new word 
     // and change the flag 
     if (isalnum(text[i]) != 0) { 
      if (new_word == false) { 
       new_word = true; 
       index_start_word = i; 
      } 

     // if it is not ascii letter or digits and a word traced early 
     // it means the word ended 
     } else { 
      if (new_word == true) { 

       // allocate a memory for a new word in the array of words 
       words[count] = malloc(i - index_start_word * sizeof(char) + 1); 

       // copy the found word from the text by indexes 
       strncpy(words[count], text + index_start_word, i - index_start_word); 

       // change the flag 
       new_word = false; 

       // increase the counter of words 
       count++; 
      } 
     }; 
    } 

    // bind the found words and it count to a structure and return it 
    ListWithLength *list_with_length = malloc(sizeof(ListWithLength)); 

    list_with_length->length = count; 
    list_with_length->list = words; 

    return list_with_length; 
} 


/* 
    Print information of a ListWithLength 
*/ 
void printListWithLength(ListWithLength *list_with_length) { 
    printf("Total items: %li\n", list_with_length->length); 
    puts("----------------------"); 
    for (int i = 0; i < list_with_length->length; ++i) { 
     printf("%d. %s\n", i + 1, list_with_length->list[i]); 
    } 
} 


int main(int argc, char const *argv[]) 
{ 

    char c_keywords[300] = "auto else long switch\ 
    break\t enum \t register typedef\ 
    \ncase extern, return union\ 
    ?char float. short unsigned\ 
    const !for signed void\ 
    continue goto sizeof volatile\ 
    .default???? if static while\ 
    do int struct,,,, _Packed\ 
    double......."; 

    ListWithLength *list_with_length = getWords(c_keywords); 
    printListWithLength(list_with_length); 

    return 0; 
} 

編譯看看結果:

$ gcc -Wall -ansi -std=c11 -o main main.c 
$ ./main 
Total items: 33 
---------------------- 
1. auto 
2. else 
3. long 
4. switch 
5. break 
6. enum 
7. register 
8. typedef 
9. case 
10. extern 
11. return 
12. union 
13. char 
14. float 
15. short 
16. unsigned 
17. const 
18. for 
19. signed 
20. void 
21. continue 
22. goto 
23. sizeof 
24. volatile 
25. default 
26. if 
27. static 
28. while 
29. do 
30. int 
31. struct 
32. Packed 
33. double