在文件中查找单词无法正常工作

时间:2019-01-09 18:33:05

标签: c string file

我正在用C编写一个函数,该函数可以读取文件并找到不在注释和字符串中的单词(例如printf(“ Hello world”),我只需要printf,“ hello”和“ world”不必计数),但在某些文件中,我的程序也计算字符串中的单词

int isDelimiter(char *delim, char c){
  int i = 0;
  while (delim[i])
  {
    if (delim[i] == c)
        return 1;
    i++;
  }
  return 0;
}

int getIdentifiers(FILE *filePointer){

  char line[256], identifier[100];

  //char delimiters[] = "\n\[]();~`!=><|*/:&% \t\"{},-+#^$'&";
  char delimiters[] = {'\n', '\"', '[', ']', '(', ')', ';', '~', '`', 
    '!', '=', '<','>', '|', '*','/',':','&',
    '%','\t', '{', '}', ',','-','+','#','^','$','&','\0'};

  int cnt=0, inWord=0, isString=0, isSingleLineComment=0, 
     isMultiComment=0, isChar=0;

  rewind(filePointer);

  while(fgets(line, sizeof(line), filePointer)!=NULL){

    int i=0, j=0;

    isSingleLineComment=0;

    while(line[i]){

      //multi line comment check
      if(line[i]=='/' && line[i+1]=='*') isMultiComment=1;

      //single line comment
      if(line[i]=='/' && line[i+1]=='/') isSingleLineComment=1;

      //ending multi line comment
      if(line[i]=='*' && line[i+1]=='/' && isMultiComment==1) isMultiComment=0;

      //checking for string
      if(line[i]=='"' && isString==0) isString=1;

      //check if assignment char is in quote
      if(line[i]=='\'' && isChar==0) isChar =1;
      else if(line[i]=='\'' && isChar==1) isChar=0;

      //splitting textline into words
      if(inWord==0){
        if(!isDelimiter(delimiters, line[i])) {
          inWord = 1;
          identifier[j] = line[i];
          j++;
        } else {
          i++;
          continue;
        }
      } else {
        //ending word
        if(isDelimiter(delimiters, line[i])) {
          if(line[i]=='"' ) isString=1;

          inWord=0;
          identifier[j]= '\0';
          j=0;

          // identifier checking
          if(!isString && !isMultiComment && !isSingleLineComment && 
             !isChar &&
             !isdigit(identifier[0])){
             cnt++;
          }
        } else {
          identifier[j]= line[i];
          j++;
        }
      }

      if(line[i]=='"' && isString){
        isString=0;
      }
      i++;
    }
  }

  return cnt;
}

我测试的文件包含:

  


int a;            
// int c;            
/ * int k;            
* /            
“ int i; \” int c;“            
int = e;

期望的返回值必须为4(我需要的单词为'int','a','int'和'e',但值为2。

1 个答案:

答案 0 :(得分:0)

扩展@MichaelDorgan的注释,关于字符串,还需要处理其他几种极端情况。这两种都会导致您当前的解析器失败:

"This string \" contains a double quote"
"This one contains ' a single quote"

我强烈建议您更改解析器的基本体系结构,使其在可以识别单词的状态下开始,但是如果您看到/* // "或{{1} },您将切换到以下状态:(A)忽略单词,并且(B)使用单独的循环使用输入,直到它正确识别出当前状态的有效终止,然后返回初始状态。

因此'将继续阅读文本,直到找到/*,而*/只是丢弃当前行的其余部分,然后重置。同样,//"向前扫描,直到找到第二个未转义的副本,而忽略了其他所有内容。在这种模式下,您需要特别注意反斜杠,以便正确处理'"\"" "\\"等内容。