在C中从char数组创建一个字符串

时间:2014-11-12 14:30:30

标签: c arrays string char

我有一段代码循环遍历char数组字符串以尝试检测单词。它会循环通过,如果检测到A - Z或a - z或_(下划线),它会将它添加到char数组中。我需要的,因为它们是单词,是能够将它们放入一个字符串,然后我可以使用另一个函数进行检查,然后可以将其丢弃。 这是我的功能:

char wholeProgramStr2[20000];
char wordToCheck[100] ="";

IdentiferFinder(char *tmp){
    //find the identifiers
    int count = 0;
    int i;
    for (i = 0; i < strlen(tmp); ++i){
        Ascii = toascii(tmp[i]);
        if ((Ascii >= 65 && Ascii <= 90) || (Ascii >= 97 && Ascii <= 122) || (Ascii == 95))
        {
            wordToCheck[i] = tmp[i];
            count++;
            printf("%c",wordToCheck[i]); 
        }
        else {
            if (count != 0){
            printf("\n");
        }
            count = 0;
        }
    }
    printf("\n");
}

目前我可以看到所有的单词,因为它会在不同的行上打印出来。

WholeProgram2的内容是文件的所有行。它是* tmp参数。

谢谢。

2 个答案:

答案 0 :(得分:3)

你描述了将一个大字符串分成小字符串(单词) 假设您正在使用普通分隔符进行解析,例如空格或制表符或换行符:

这是一个三步法
首先 ,获取有关源字符串的信息 第二 ,动态创建目标数组以满足您的尺寸需求 第三次 ,循环strtok()以填充目标字符串数组(char **)

(第四个是释放创造的内存,你需要做的事)
提示:原型可能如下所示:
// void Free2DCharArray(char ** a,int numWords);

代码示例:

void FindWords(char **words, char *source);
void GetStringParams(char *source, int *longest, int *wordCount);
char ** Create2DCharArray(char **a, int numWords, int maxWordLen);
#define DELIM " \n\t"

int main(void)
{
    int longestWord = 0, WordCount = 0;
    char **words={0};
    char string[]="this is a bunch of test words";

    //Get number of words, and longest word, use in allocating memory
    GetStringParams(string, &longestWord, &WordCount);

    //create array of strings with information from source string
    words = Create2DCharArray(words, WordCount, longestWord);

    //populate array of strings with words
    FindWords(words, string);

    //Do not forget to free words (left for you to do)
    return 0;   
}

void GetStringParams(char *source, int *longest, int *wordCount)
{
    char *tok;
    int i=-1, Len = 0, KeepLen = 0;
    char *cpyString = 0;
    cpyString = calloc(strlen(source)+1, 1);
    strcpy(cpyString, source);
    tok=strtok(source, DELIM);
    while(tok)
    {
        (*wordCount)++;
        Len = strlen(tok);
        if(Len > KeepLen) KeepLen = Len;
        tok = strtok(NULL, DELIM);
    }
    *longest = KeepLen;
    strcpy(source, cpyString);//restore contents of source
}

void FindWords(char **words, char *source)             
{
    char *tok;
    int i=-1;

    tok = strtok(source, DELIM);
    while(tok)
    {
        strcpy(words[++i], tok);
        tok = strtok(NULL, DELIM);
    }
}

char ** Create2DCharArray(char **a, int numWords, int maxWordLen)
{
    int i;
    a = calloc(numWords, sizeof(char *));
    if(!a) return a;
    for(i=0;i<numWords;i++)
    {
        a[i] = calloc(maxWordLen + 1, 1);       
    }
    return a;
}

答案 1 :(得分:2)

如果您的目标是查找字符数组中的单词,您可能希望首先找到一个有效的字符序列(并且您似乎正在尝试这样做),并且一旦找到一个,进行二次检查以确定它是否是真正的单词。如果它确实是一个单词,那么您可以决定保留它以供进一步使用。

这种方法的优点是你不需要保留一个大的潜在单词缓冲区,你只需要一个固定的缓冲区,其大小与字典中最大的单词相匹配。事实上,你可能甚至不需要一个缓冲区,只是一个指向char数组的指针,指向一个可能的单词的开头,一个int(虽然一个字节可能就足够了)来跟踪那个单词的长度。

// structure to store a word match in array
typedef struct token_s {
  int length;
  const char *data;
} token_t;

void nextToken(const char *tmp, int len, token_t *to){
  char *start = NULL;
  while (len){
    if (start) {
      // search for end of current word
      if (!isalpha(*tmp)) {
        to->data = start;
        to->length = tmp - start;
        return;
      }
    } else { 
      // search for beginning of next word
      if (isalpha(*tmp))
        start = tmp;
    }
    tmp++;
    len--;
  } // while
  if (start) {
    to->data = start;
    to->length = tmp - start;  
  }
}

简单地通过:

  • char数组的开头,如果不超出数组末尾,则为to->data + to->length + 1
  • 要扫描的char数组的下雨长度
  • 指向归零token_t
  • 的指针

每次调用nextToken,并检查令牌的内容,以确定它是否找到了候选人;如果没有,你知道阵列已被完全扫描。

void scanArray(const char *tmp, int len){
  while (len > 0){
    token_t to;
    to.data = NULL;
    to.length =0;
    nextToken(tmp, len, &to);
    if (to.data) {
      tmp += to.length +1;
      len -= to.length +1;     
      // process token here...
    } else break;
  } // while
}

我使用isalpha来测试有效字符,但您需要通过自己的函数替换它。而且您必须在scanArray的正文中插入自己的代码进行二次检查。