C项目赢得';不要删除占据整行的注释
因此,我正在阅读K&RCBook,我的代码中有一个我无法理解的bug 程序应该删除C程序中的所有注释。显然我只是在用标准输入法C项目赢得';不要删除占据整行的注释,c,C,因此,我正在阅读K&RCBook,我的代码中有一个我无法理解的bug 程序应该删除C程序中的所有注释。显然我只是在用标准输入法 #include <stdio.h> int getaline (char s[], int lim); #define MAXLINE 1000 //maximum number of characters to put into string[] #define OUTOFCOMMENT 0 #define INASINGLECOMMENT 1 #
#include <stdio.h>
int getaline (char s[], int lim);
#define MAXLINE 1000 //maximum number of characters to put into string[]
#define OUTOFCOMMENT 0
#define INASINGLECOMMENT 1
#define INMULTICOMMENT 2
int main(void)
{
int i;
int isInComment;
char string[MAXLINE];
getaline(string, MAXLINE);
for (i = 0; string[i] != EOF; ++i) {
//finds whether loop is in a comment or not
if (string[i] == '/') {
if (string[i+1] == '/')
isInComment = INASINGLECOMMENT;
if (string[i+1] == '*')
isInComment = INMULTICOMMENT;
}
//fixes the problem of print messing up after the comment
if (isInComment == INASINGLECOMMENT && string[i] == '\0')
printf("\n");
//if the line is done, restates all the variables
if (string[i] == '\0') {
getaline(string, MAXLINE);
i = 0;
if (isInComment != INMULTICOMMENT)
isInComment = OUTOFCOMMENT;
}
//prints current character in loop
if(isInComment == OUTOFCOMMENT && string[i] != EOF)
printf("%c", string[i]);
//checks to see of multiline comment is over
if(string[i] == '*' && string[i+1] == '/' ) {
++i;
isInComment = OUTOFCOMMENT;
}
}
return 0;
}
在注释开始之前没有任何内容,它将打印该注释,即使它不应该打印
我以为我取得了很好的进步,但这个错误真的阻碍了我。我希望这不是我错过的超简单的事情
编辑:忘记getaline函数
//puts line into s[], returns length of that line
int getaline(char s[], int lim)
{
int c, i;
for (i = 0; i < lim-1 && (c = getchar()) != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
//将行放入s[],返回该行的长度
int getaline(字符s[],int lim)
{
int c,i;
对于(i=0;i
当您开始一个新行时,您将i
初始化为0。但在下一次迭代中:
for (i = 0; string[i] != EOF; ++i)
i
将递增,因此您将以索引1
开始新行。因此,当该行以/
开头时会出现错误
您可以看到,如果您改为编写以下内容,它将解决问题:
if (string[i] == '\0') {
getaline(string, MAXLINE);
i = 0;
if (isInComment != INMULTICOMMENT)
isInComment = OUTOFCOMMENT;
}
尽管通常认为在循环内修改循环索引的
是不好的风格。您可以以更具可读性的方式重新设计实现。代码中存在许多问题:
isInComment
未在函数main
中初始化
- 正如其他人指出的,
string[i]!=EOF
错误。您需要更精确地测试文件结尾,尤其是对于不以换行符结尾的文件。仅当char
类型为有符号且EOF
为有效的signed char
值时,此测试才有效。然而,它会错误地停在一个零散的\377
字符上,这在字符串或注释中是合法的
- 当检测到行尾时,您读取另一行并将
i
重置为0
,但在再次测试单行注释之前,for循环将增加i。。。这就是臭虫李>
- 您不处理特殊情况,例如
/*/*/
或//*
- 您不处理字符串。这不是注释:
“/*”
,也不是注释:“//”
- 在行尾(转义换行符)不处理
\
。这可以用来扩展单行注释、字符串等。还有一些更微妙的情况与\
处理有关,如果您确实想要完整性,您也应该处理三角图
- 您的实现对行大小有限制,这是不需要的
分配给你的问题有点棘手。与其读取和解析行,不如一次读取一个字符,并实现一个状态机来解析转义换行、字符串和这两种注释样式。如果使用此方法正确,代码就不会太难。getaline函数中有什么?string[i]!=EOF
似乎不正确。我想应该是string[I]!='\0'
字符串[i]!=EOF代码>-->字符串[i]!=0;代码>用于start.Dang。我需要修改我的代码。谢谢你指出了所有的缺点。一开始就这么糟糕是正常的吗?非常令人沮丧。别担心,你正在解决的问题实际上相当困难。这里有一个复制品:但他们也没有弄对。
for (i = 0; string[i] != EOF; ++i)
if (string[i] == '\0') {
getaline(string, MAXLINE);
i = 0;
if (isInComment != INMULTICOMMENT)
isInComment = OUTOFCOMMENT;
}