从C程序中删除注释
下面是我从C程序中删除注释的代码。但是注释行不会被删除。它删除从C程序中删除注释,c,comments,C,Comments,下面是我从C程序中删除注释的代码。但是注释行不会被删除。它删除/*和*/,但不删除此分隔符之间的句子 #include <stdio.h> main(int argc, char *argv[]) { FILE *fp, *ft; char ch; if (argc < 3) { printf("No file name given"); } fp = fopen(argv[1], "r"); ft = fope
/*
和*/
,但不删除此分隔符之间的句子
#include <stdio.h>
main(int argc, char *argv[]) {
FILE *fp, *ft;
char ch;
if (argc < 3) {
printf("No file name given");
}
fp = fopen(argv[1], "r");
ft = fopen(argv[2], "w");
if (fp == NULL)
printf("Opening error");
if (ft == NULL)
printf("Opening error");
while (1) {
ch = fgetc(fp);
if (ch == EOF)
break;
if (ch == '/') {
ch = fgetc(fp);
if (ch == '*') {
putc(' ', ft);
}
} else if (ch == '*') {
ch = fgetc(fp);
if (ch == '/') {
putc(' ', ft);
}
} else {
putc(ch, ft);
}
}
fclose(fp);
fclose(ft);
}
#包括
main(int argc,char*argv[]){
文件*fp,*ft;
char ch;
如果(argc<3){
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
而(1){
ch=fgetc(fp);
如果(ch==EOF)
打破
如果(ch=='/'){
ch=fgetc(fp);
如果(ch=='*'){
putc('',英尺);
}
}else if(ch=='*'){
ch=fgetc(fp);
如果(ch=='/'){
putc('',英尺);
}
}否则{
putc(ch,ft);
}
}
fclose(fp);
fclose(ft);
}
请帮助我删除注释行。您的最后一个else部分正在写入所有不是
'/'
和'*'的字符。
。
我已经更改了下面的代码*******附加行*******显示更改的零件。试试吧,告诉我??好运气
#include<stdio.h>
main(int argc,char*argv[])
{
FILE *fp,*ft;
char ch;
int flag=0; //**********************additional line********
if(argc<3)
{
printf("No file name given");
}
fp=fopen(argv[1],"r");
ft=fopen(argv[2],"w");
if(fp==NULL)
printf("Opening error");
if(ft==NULL)
printf("Opening error");
while(1)
{
ch=fgetc(fp);
if(ch==EOF)
break;
if(ch=='/')
{
ch=fgetc(fp);
if(ch=='*')
{
flag=1; //**********************additional line********
putc(' ',ft);
}
}
else if (ch=='*')
{
ch=fgetc(fp);
if(ch=='/')
{
flag=0;//**********************additional line********
putc(' ',ft);
}
}
if(flag==0) //**********************additional line********
{
putc(ch,ft);
}
}
fclose(fp);
fclose(ft);
}
#包括
main(int argc,char*argv[])
{
文件*fp,*ft;
char ch;
int flag=0;//**********************附加行********
如果(argc您的代码正确地标识了注释开始序列“/”和注释结束序列“/”,并删除了它们,但没有删除它们之间的内容(例如,一个标志应该这样做)
/*
*如果检测到注释,则标志=1
*否则,标志=0
*/
如果(标志==0)
{
putc(ch,ft);
}
如果代码保持原样,它不仅会删除注释中的所有“/”,还会删除文件中的任何位置。我至少可以想到一个坏结果(当调用诸如
、
、
等标题时)
由于注释的开始和结束序列有两个字符宽,我建议您使用两个“游标”来读取fp,就好像每个循环读取两个字符一样(尽管它可以工作,但出于简单性和可读性的原因,它不处理边缘情况,例如EOF之前的非闭合注释,或闭合注释序列之后的EOF)
#包括
int
main(int argc,char*argv[])
{
文件*fp,*ft;
char ch,nextc;
如果(argc<3)
{
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
nextc=fgetc(fp);
while(nextc!=EOF)
{
ch=nextc;
nextc=fgetc(fp);
如果((ch='/')&&(nextc=='*'))
{
nextc=fgetc(fp);
而((ch!='*')&&(nextc!='/'))/*展开,直到注释结束*/
{
ch=nextc;
nextc=fgetc(fp);
}
ch=fgetc(fp);
nextc=fgetc(fp);
}
putc(ch,ft);
}
fclose(fp);
fclose(ft);
返回0;
}
希望这有帮助。只需更改上面代码中的行即可
而((ch!='*')和&(nextc!='/'))
到
虽然(!((ch='*')和&(nextc=='/'))对于这个问题,大多数答案只处理多行注释(/../),但也可能有单行注释。
因此,要处理单行注释,krouis的代码中有轻微的修改
#include <stdio.h>
int main (int argc, char *argv[])
{
FILE *fp, *ft;
char ch, nextc;
if (argc < 3)
{
printf ("No file name given");
}
fp = fopen (argv[1], "r");
ft = fopen (argv[2], "w");
if (fp == NULL)
printf ("Opening error");
if (ft == NULL)
printf ("Opening error");
nextc = fgetc (fp);
while (nextc != EOF)
{
ch = nextc;
nextc = fgetc (fp);
if ((ch == '/') && (nextc == '*'))
{
ch = fgetc (fp);
nextc = fgetc (fp);
while (!((ch == '*') && (nextc == '/'))) /* unroll until the end of comment*/
{
ch = nextc;
nextc = fgetc (fp);
}
nextc = fgetc (fp);
continue;
}else if((ch=='/') && (nextc == '/')) // block to handle single line comment.
{
nextc = fgetc (fp);
while (!(nextc == '\n')){
nextc = fgetc (fp);
}
nextc = fgetc (fp);
continue;
}
putc (ch, ft);
}
fclose (fp);
fclose (ft);
return 0;
}
#包括
int main(int argc,char*argv[])
{
文件*fp,*ft;
char ch,nextc;
如果(argc<3)
{
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
nextc=fgetc(fp);
while(nextc!=EOF)
{
ch=nextc;
nextc=fgetc(fp);
如果((ch='/')&&(nextc=='*'))
{
ch=fgetc(fp);
nextc=fgetc(fp);
而(!((ch='*')和&(nextc=='/'))/*展开,直到注释结束*/
{
ch=nextc;
nextc=fgetc(fp);
}
nextc=fgetc(fp);
继续;
}else if((ch='/')&&&(nextc=='/')/)块处理单行注释。
{
nextc=fgetc(fp);
而(!(nextc=='\n')){
nextc=fgetc(fp);
}
nextc=fgetc(fp);
继续;
}
putc(ch,ft);
}
fclose(fp);
fclose(ft);
返回0;
}
您还必须处理以下事项
printf("Hello World /*a b c*/ ");
因为/*a b c*/这里实际上不是注释您的代码中存在多个问题:
- 不应忽略
main
的返回类型。隐式int
已过时,C标准不再允许。原型应为int main(int argc,char*argv[])
- 如果未将命令行参数传递给程序,则应在打印错误消息后退出,错误消息应输出到
stderr
,而不是stdout
- 如果无法打开输入文件,则程序不应创建输出文件
- 如果其中一个
fopen
失败,程序应该停止,而不是进入未定义行为的领域
ch
必须具有类型int
而不是char
,才能使测试(ch==EOF)
正常运行
- 您可以正确识别序列
/*
和*/
,并用单个
替换它们,但它实际上会删除所有其他出现的/
和*
以及后续字符,并且您没有跳过这两个字符的任何规定
main
应返回0
还要注意,如果
#include <stdio.h>
/* read the next byte from the C source file, handing escaped newlines */
int getcpp(FILE *fp) {
int ch;
while ((ch = getc(fp)) == '\\') {
if ((ch = getc(fp)) != '\n') {
ungetc(ch, fp);
return '\\';
}
}
return ch;
}
/* read and write character and string constants */
int skipstr(int cch, FILE *fp, FILE *ft) {
int ch;
putc(cch, ft);
while ((ch = getcpp(fp)) != EOF) {
putc(ch, ft);
if (ch == cch)
return 0;
if (ch == '\\') {
if ((ch = getcpp(fp)) == EOF)
return EOF;
putc(ch, ft);
}
}
return EOF;
}
int main(int argc, char *argv[]) {
FILE *fp, *ft;
int ch;
if (argc < 3) {
fprintf(stderr, "Missing arguments. Need input and output filenames\n");
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Cannot open input file %s\n", argv[1]);
return 1;
}
if ((ft = fopen(argv[2], "w")) == NULL) {
fprintf(stderr, "Cannot open output file %s\n", argv[2]);
return 1;
}
while ((ch = getcpp(fp)) != EOF) {
if (ch == '\'' || ch == '"') {
if (skipstr(ch, fp, ft)) {
fprintf(stderr, "unterminated string or character constant\n");
break;
}
continue;
}
if (ch == '/') {
if ((ch = getcpp(fp)) == '*') {
/* multi-line comment */
int lastc = 0;
while ((ch = getcpp(fp)) != EOF) {
if (ch == '/' && lastc == '*') {
break;
}
lastc = ch;
}
if (ch == EOF) {
fprintf(stderr, "unterminated comment\n");
break;
}
ch = ' ';
} else if (ch == '/') {
/* single-line comment */
while ((ch = getcpp(fp)) != EOF && ch != '\n')
continue;
if (ch == EOF)
break;
} else {
putc('/', ft);
}
}
putc(ch, ft);
}
fclose(fp);
fclose(ft);
return 0;
}
#include <stdio.h>
#include <string.h>
#define READ 0
#define SINGLE_LINE_COMMENT 1
#define MULTILINE_COMMENT 2
#define STRING_READ 3
#define CHAR_READ 4
int row = 1;
int col = 0;
int er_line = 0;
int er_col = 0;
void read_source(FILE *src, FILE *dst, int flag, char prev_char, int past_read)
{
if (feof(src))
{
if (flag == STRING_READ)
{
printf("Error : non-terminatig string at line :%d col :%d \n", er_line, er_col);
}
if (flag == CHAR_READ)
{
printf("Error : non-terminatig char constant at line :%d col :%d \n", er_line, er_col);
}
if (flag == MULTILINE_COMMENT)
{
printf("Error : comment reach to end of file at line :%d col :%d \n", er_line, er_col);
}
fclose(src);
fclose(dst);
return;
}
char ch = fgetc(src);
past_read++;
if (ch == '\n')
{
row++;
col = 0;
}
else
{
col++;
}
char next_ch = '\0';
switch (ch)
{
case '\n':
if (flag == SINGLE_LINE_COMMENT)
{
flag = READ;
past_read = 0;
}
else
{
if (flag == STRING_READ)
{
printf("Error : non-terminatig string at line :%d col :%d \n", er_line, er_col);
return;
}
if (flag == CHAR_READ)
{
printf("Error : non-terminatig char constant at line :%d col :%d \n", er_line, er_col);
return;
}
}
break;
case '/':
next_ch = fgetc(src);
if (next_ch == '/')
{
if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
{
flag = SINGLE_LINE_COMMENT;
er_line = row;
er_col = col;
past_read = 0;
}
}
else
{
if (next_ch == '*')
{
if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
{
flag = MULTILINE_COMMENT;
er_line = row;
er_col = col;
past_read = 0;
}
}
else
{
fseek(src, -1, SEEK_CUR);
}
}
break;
case '"':
if (prev_char != '\\')
{
if (flag == STRING_READ)
{
flag = READ;
past_read = 0;
}
else
{
if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
{
flag = STRING_READ;
er_line = row;
er_col = col;
past_read = 0;
}
}
}
break;
case '\'':
if (prev_char != '\\')
{
if (flag == CHAR_READ)
{
flag = READ;
past_read = 0;
}
else
{
if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
{
flag = CHAR_READ;
er_line = row;
er_col = col;
past_read = 0;
}
}
}
else
{
if (flag == CHAR_READ)
{
if (past_read > 2)
{
flag = READ;
past_read = 0;
}
}
}
break;
case '*':
if (flag == MULTILINE_COMMENT)
{
next_ch = fgetc(src);
if (next_ch == '/')
{
ch = '\0';
flag = READ;
past_read = 0;
}
else
{
fseek(src, -1, SEEK_CUR);
}
}
break;
}
//to work with char constant
if (flag == CHAR_READ)
{
if (ch != '\\')
{
if (prev_char != '\\')
{
if (past_read > 3)
{
printf(" Error : non-terminatig char constant at line :%d col :%d\n", er_line, er_col);
return;
}
}
}
else
{
if (past_read > 3)
{
printf(" Error : non-terminatig char constant at line :%d col :%d\n", er_line, er_col);
return;
}
}
}
if (flag != MULTILINE_COMMENT && flag != SINGLE_LINE_COMMENT && ch != '\0' && ch != EOF)
{
fputc(ch, dst);
}
read_source(src, dst, flag, ch, past_read);
return;
}
int main(int argc, char **argv)
{
FILE *fp = fopen(argv[1], "r");
FILE *fp2 = NULL;
if (fp == NULL)
{
printf("Unable to open file %s\n", argv[1]);
return 0;
}
fp2 = fopen(argv[2], "w");
if (fp2 == NULL)
{
printf("Unable to open file %s\n", argv[2]);
}
read_source(fp, fp2, READ, '\0', 0);
return 0;
}
/* This file is to remove all comments from a c/c++ source file */
/* Modified by John Dai 2020-05-06 */
#include <stdio.h>
int main (void)
{
char *sourceFile = "D:/Temp/MyCfile.cpp"; //your source code
char *outputFile = "D:/Temp/MyCfileWoComments.cpp"; //output file
FILE *fp, *ft;
char ch, nextc;
fp = fopen (sourceFile, "r");
ft = fopen (outputFile, "w");
if (fp == NULL) {printf ("Error in opening source file\n"); return 1;}
if (ft == NULL) {printf ("Error in opening output file\n"); return 1;}
nextc = fgetc (fp);
while (nextc != EOF)
{
ch = nextc;
nextc = fgetc (fp);
if ((ch == '/') && (nextc == '/'))
{
nextc = fgetc (fp);
while (nextc != '\n') {// move to the end of line
nextc = fgetc (fp);
}
ch = nextc; //end of line character
nextc = fgetc(fp); //read 1st character from a new line
}
else if ((ch == '/') && (nextc == '*')){
{
nextc = fgetc (fp);
while (!((ch == '*') && (nextc == '/'))) {/* move to the end of comment*/
ch = nextc;
nextc = fgetc (fp);
}
ch = fgetc (fp); //read first character after the end of comment block
nextc = fgetc (fp);
}
}
putc (ch, ft);
}
fclose (fp);
fclose (ft);
return 0;
}