我正在用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。
答案 0 :(得分:0)
扩展@MichaelDorgan的注释,关于字符串,还需要处理其他几种极端情况。这两种都会导致您当前的解析器失败:
"This string \" contains a double quote"
"This one contains ' a single quote"
我强烈建议您更改解析器的基本体系结构,使其在可以识别单词的状态下开始,但是如果您看到/*
//
"
或{{1} },您将切换到以下状态:(A)忽略单词,并且(B)使用单独的循环使用输入,直到它正确识别出当前状态的有效终止,然后返回初始状态。
因此'
将继续阅读文本,直到找到/*
,而*/
只是丢弃当前行的其余部分,然后重置。同样,//
和"
向前扫描,直到找到第二个未转义的副本,而忽略了其他所有内容。在这种模式下,您需要特别注意反斜杠,以便正确处理'
,"\""
"\\"
等内容。