我正在用 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。
最佳答案
扩展@MichaelDorgan 的评论,您还需要处理有关字符串的其他几种边缘情况。这两种情况都会导致您当前的解析器失败:
"This string \" contains a double quote"
"This one contains ' a single quote"
我强烈建议更改解析器的基本架构,以在识别单词的状态下启动,但如果您看到任何 /*
//
"
或 '
您切换到 (A) 忽略单词的状态,并且 (B) 使用单独的循环来消耗输入,直到它正确识别当前状态的有效终止,之后返回到初始状态。
因此 /*
将继续读取文本,直到找到 */
,而 //
只是丢弃当前行的其余部分然后重置。同样,"
和 '
向前扫描,直到找到第二个未转义的副本,忽略其他所有内容。在此模式下,您需要特别注意反斜杠,以便正确处理内容如 "\""
、"\\"
"\\\""
等
关于c - 在文件中查找单词无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54116297/