【发布时间】:2018-12-26 11:37:05
【问题描述】:
我有一个函数必须通过某些分隔符将从文件读取的行溢出到单词中(分隔符检查由另一个函数进行)但我的代码通过分隔符列表中未包含的分隔符拆分字符串 [一个数组分隔符]:
void getIdentifiers() {
FILE *filePointer;
char fileName[FILENAME_MAX], line[256], identifier[100];
char delimiter[] = {
'[', ']', '(', ')', ';', '!', '=', '>', '<', '|', '*', '/', ':',
'&', '%', ' ', '\n', '\t', '"', '{', '}', ',', '-', '+', '#' };
int cnt = 0, inWord = 0, isString = 0, isSingleLineComment = 0, isMultiComment = 0, isChar = 0;
printf("\n Enter filename:\n");
flush(stdin);
if (!fgets(fileName, FILENAME_MAX, stdin)) {
printf("\nError reading filename");
return;
}
if (fileName[strlen(fileName) - 2] != 'c' || fileName[strlen(fileName) - 3] != '.') {
printf("\nInvalid source file name\n");
return;
}
fileName[strlen(fileName) - 1] = '\0';
filePointer = fopen(fileName, "r");
if (filePointer == NULL) {
printf("\nError opening file");
return;
}
while (fgets(line, sizeof(line) / sizeof(line[0]), filePointer) != NULL) {
if (ferror(filePointer)) {
printf("\nError reading the file");
return;
}
int i = 0, j = 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;
else if (line[i] == '"' && isString == 1)
isString = 0;
//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(delimiter, line[i])) {
inWord = 1;
identifier[j] = line[i];
j++;
} else {
i++;
continue;
}
} else {
//ending word
if (isDelimiter(delimiter, line[i])) {
inWord = 0;
identifier[j] = 0;
j = 0;
// identifier checking
if (!isString && !isMultiComment && !isSingleLineComment
&& !isChar) {
cnt++;
printf("\n%s", identifier);
}
} else {
identifier[j] = line[i];
j++;
}
}
i++;
}
isSingleLineComment = 0;
}
printf("\n Number of identifiers is %d", cnt);
}
int isDelimiter(char *delim, char c) {
int i = 0;
while (delim[i]) {
if (delim[i] == c)
return 1;
i++;
}
return 0;
}
我尝试读取的文件包含:
Turbo direct injection
预期的输出是:
Turbo
direct
injection
但我得到了:
Turbo
di
ect
inject
o
【问题讨论】:
-
它有帮助,但现在没有显示最后一个字
-
除了将
delimiter视为非空终止字符串之外,还有其他一些事情......嗯,奇怪(或错误):首先,调用fflushon C 规范中明确提到了仅输入流(如stdin)作为未定义的行为。即使某些 C 库实现了它,它也不是可移植的,应该避免使用。此外,由于sizeof(char)被指定为始终为1,表达式sizeof(line)/sizeof(line[0])等于sizeof(line)。如果fileName短于两个字符会怎样?还是比FILENAME_MAX更长? -
在使用它之前声明 isDelimiter,或将其定义移到其使用之上