如何删除//评论 [英] How to remove // comments

查看:68
本文介绍了如何删除//评论的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,激烈的辩论开始是因为贫穷的希思菲尔德先生

无法用//评论编写程序。


这是一个实用工具他,所以他可以(最后)编译我的

程序:-)


更严重的是,这段代码需要560个字节。太棒了不是吗? C非常好,你可以用几个字节来做很棒的事情。


显然我已经避免了这里,考虑到他的迂腐

编译器标志,任何C99问题,所以它将在过时的

编译器中编译,并且只需~600字节就可以在烤面包机中运行它!


----------------------------------------------- ---------------切到这里


/ *这个程序读取一个C源文件并将其修改为stdout

所有//注释将替换为/ * ... * / comments,以便轻松移植到旧环境或将其发布到usenet中,其中

//注释可以分成几行,然后搞砸了。

* /


#include< stdio.h>


/ *此函数读取一个字符并将其写入stdout * /

static int Fgetc(FILE * f)

{

int c = fgetc(f);

if(c!= EOF)

putchar(c);

返回c;

}

/ *此函数跳过字符串* /

static int ParseString(FILE * f)

{

int c = Fgetc(f);

while(c!= EOF&& c!=''"''){

if(c ==''\\'')

c = Fgetc(f);

if(c!= EOF)

c = Fgetc(f);

}

if(c =='' "'')

c = Fgetc(f);

返回c;

}

/ *跳过多行注释* /

static int ParseComment(FILE * f)

{

int c = Fgetc(f);


while(1){

while(c!=''*''){

c = Fgetc(f);

if(c == EOF)

返回EOF;

}

c = Fgetc(f);

if(c ==''/'')

休息;

}

返回Fgetc(f); < br $>
}


/ *跳过//评论。注意我们在这里使用fgetc而不是Fgetc * /

/ *因为我们想在获得echo之前修改输出* /

static int ParseCppComment(FILE * f)

{

int c = fgetc(f);


while(c!= EOF&& c!=' '\ n''){

putchar(c);

c = fgetc(f);

}

if(c ==''\ n''){

puts(" * /");

c = Fgetc(f);

}

返回c;

}


/ *检查'a'后面是否有评论'/''char * /

static int CheckComment(int c,FILE * f)

{

if(c =='' /''){

c = fgetc(f);

if(c ==''*''){

putchar(' '*'');

c = ParseComment(f);

}

else if(c ==''/''){

putchar(''*'');

c = ParseCppComment(f);

}

else {

putchar(c);

c = Fgetc( f);

}

}

返回c;

}


/ *在简单引号之间跳过字符* /

static int ParseQuotedChar(FILE * f)

{

int c = Fgetc( f);

while(c!= EOF&& c!=''\''''){

if(c ==''\\'')

c = Fgetc(f);

if(c!= EOF)

c = Fgetc(f);

}

if(c == ''\'''')

c = Fgetc(f);

返回c;

}

int main(int argc,char * argv [])

{

FILE * f;

int c;

if(argc == 1){

fprintf(stderr," Usage:%s< file.c> \ n",argv [0]);

返回EXIT_FAILURE;

}

f = fopen(argv [1]," r");

if(f = = NULL){

fprintf(stderr,找不到%s \ n,argv [1]);

返回EXIT_FAILURE;

}

c = Fgetc(f);

而(c!= EOF){

/ *注意每一个开关必须使字符* /

/ *读取,以便我们避免无限循环。 * /

开关(c){

case''"'':

c = ParseString(f);

休息;

case''/'':

c = CheckComment(c,f);

休息;

case''\'''':

c = ParseQuotedChar(f);

休息;

默认值:

c = Fgetc(f);

}

}

fclose(f);

返回0;

}

解决方案

jacob navia说:


最近,由于贫穷的希思菲尔德先生开始激烈辩论

无法用//评论编写程序。



不是这样。使用//评论编译程序并不困难。在

gcc下。我所要做的就是在不合格的模式下调用gcc,因此需要提供有用的诊断信息的机会 - 我不准备的事情

轻松做。


这是他的一个实用程序,这样他就可以(最后)编译我的

程序:-)



唉,还没有。你看,实用程序本身不会编译:


foo.c:在函数`main'':

foo.c:104:` EXIT_FAILURE''未声明(在此函数中首次使用)

foo.c:104 :(每个未声明的标识符仅报告一次

foo.c:104:对于每个函数它出现在。)

make:*** [foo.o]错误1


有时,言语让我失望。

-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上面的域名(但显然放弃了www)


jacob navia写道:
< blockquote class =post_quotes>
...贫穷的希思菲尔德......这是他的实用工具......



乏味幼稚。


------------------------------------ --------------------------在这里剪切


/ *这个程序读取一个C源文件和将其修改为stdout

所有//注释将替换为/ * ... * / comments,以便轻松



也许你应该编写一个实用程序来修复嵌套的注释,这些注释不会被C90或C99允许。


移植到旧环境或发布它在usenet中,其中

//注释可以分成几行,并且搞砸了。

* /



我确定有另外一行perl脚本浮动。


#include< stdio.h>



此标题是否定义您使用的标识符EXIT_FAILURE

进一步上?如果是这样,你的实现就不符合要求了。


< snip>


一些测试用例供你考虑......

int c = a // * ... * /

b;

int d =''??''''; //这是//评论,翻译好了吗?


-

彼得


jacob navia写道:


最近,由于贫穷的希思菲尔德先生开始激烈辩论

无法编制程序//评论。


这是他的实用程序,所以他可以(最后)编译我的

程序:-)



嘿,谢谢:)我的TODO列表中的一件事是

编写这样的实用程序,所以我可以用ANSI编译一个大项目br />
一致性模式并查看编译器是否会抛出任何

错误。项目来源符合(afaik!),除了

使用//评论。


Recently, a heated debate started because of poor mr heathfield
was unable to compile a program with // comments.

Here is a utility for him, so that he can (at last) compile my
programs :-)

More seriously, this code takes 560 bytes. Amazing isn''t it? C is very
ompact, you can do great things in a few bytes.

Obviously I have avoided here, in consideration for his pedantic
compiler flags, any C99 issues, so it will compile in obsolete
compilers, and with only ~600 bytes you can run it in the toaster!

--------------------------------------------------------------cut here

/* This program reads a C source file and writes it modified to stdout
All // comments will be replaced by /* ... */ comments, to easy the
porting to old environments or to post it in usenet, where
// comments can be broken in several lines, and messed up.
*/

#include <stdio.h>

/* This function reads a character and writes it to stdout */
static int Fgetc(FILE *f)
{
int c = fgetc(f);
if (c != EOF)
putchar(c);
return c;
}

/* This function skips strings */
static int ParseString(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != ''"'') {
if (c == ''\\'')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == ''"'')
c = Fgetc(f);
return c;
}
/* Skips multi-line comments */
static int ParseComment(FILE *f)
{
int c = Fgetc(f);

while (1) {
while (c != ''*'') {
c = Fgetc(f);
if (c == EOF)
return EOF;
}
c = Fgetc(f);
if (c == ''/'')
break;
}
return Fgetc(f);
}

/* Skips // comments. Note that we use fgetc here and NOT Fgetc */
/* since we want to modify the output before gets echoed */
static int ParseCppComment(FILE *f)
{
int c = fgetc(f);

while (c != EOF && c != ''\n'') {
putchar(c);
c = fgetc(f);
}
if (c == ''\n'') {
puts(" */");
c = Fgetc(f);
}
return c;
}

/* Checks if a comment is followed after a ''/'' char */
static int CheckComment(int c,FILE *f)
{
if (c == ''/'') {
c = fgetc(f);
if (c == ''*'') {
putchar(''*'');
c = ParseComment(f);
}
else if (c == ''/'') {
putchar(''*'');
c = ParseCppComment(f);
}
else {
putchar(c);
c = Fgetc(f);
}
}
return c;
}

/* Skips chars between simple quotes */
static int ParseQuotedChar(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != ''\'''') {
if (c == ''\\'')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == ''\'''')
c = Fgetc(f);
return c;
}
int main(int argc,char *argv[])
{
FILE *f;
int c;
if (argc == 1) {
fprintf(stderr,"Usage: %s <file.c>\n",argv[0]);
return EXIT_FAILURE;
}
f = fopen(argv[1],"r");
if (f == NULL) {
fprintf(stderr,"Can''t find %s\n",argv[1]);
return EXIT_FAILURE;
}
c = Fgetc(f);
while (c != EOF) {
/* Note that each of the switches must advance the character */
/* read so that we avoid an infinite loop. */
switch (c) {
case ''"'':
c = ParseString(f);
break;
case ''/'':
c = CheckComment(c,f);
break;
case ''\'''':
c = ParseQuotedChar(f);
break;
default:
c = Fgetc(f);
}
}
fclose(f);
return 0;
}

解决方案

jacob navia said:

Recently, a heated debate started because of poor mr heathfield
was unable to compile a program with // comments.

Not so. It''s not difficult to compile a program with // "comments" under
gcc. All I have to do is invoke gcc in non-conforming mode, thus foregoing
opportunities for useful diagnostic messages - something I''m not prepared
to do lightly.

Here is a utility for him, so that he can (at last) compile my
programs :-)

Alas, not yet. You see, the utility itself won''t compile:

foo.c: In function `main'':
foo.c:104: `EXIT_FAILURE'' undeclared (first use in this function)
foo.c:104: (Each undeclared identifier is reported only once
foo.c:104: for each function it appears in.)
make: *** [foo.o] Error 1

Sometimes, words fail me.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


jacob navia wrote:

... poor mr heathfield ... Here is a utility for him ...

Tediously childish.

--------------------------------------------------------------cut here

/* This program reads a C source file and writes it modified to stdout
All // comments will be replaced by /* ... */ comments, to easy the

Perhaps you should write a utility that also fixes nested comments that
are not allowed by C90 or C99.

porting to old environments or to post it in usenet, where
// comments can be broken in several lines, and messed up.
*/

I''m sure there are alternative one line perl scripts floating around.

#include <stdio.h>

Does this header define the identifier EXIT_FAILURE which you use
further on? If so, your implementation is not conforming.

<snip>

Some test cases for you to consider...

int c = a //* ... */
b;
int d = ''??''''; // this is a // comment, is it translated?

--
Peter


jacob navia wrote:

Recently, a heated debate started because of poor mr heathfield
was unable to compile a program with // comments.

Here is a utility for him, so that he can (at last) compile my
programs :-)

Hey, thanks :) One of the things on my TODO list was to
write such a utility, so I can compile a large project in ANSI
conformance mode and see if the compiler throws up any
errors. The project source is conforming (afaik!) except for the
use of // comments.


这篇关于如何删除//评论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆