如何删除//评论 [英] How to remove // comments
问题描述
最近,激烈的辩论开始是因为贫穷的希思菲尔德先生
无法用//评论编写程序。
这是一个实用工具他,所以他可以(最后)编译我的
程序:-)
更严重的是,这段代码需要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 thePerhaps 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屋!