堆栈溢出!我正在学习C技术。我有一个获取输入文件,搜索文件并将内容写到输出文件而无需注释的函数。 该功能有效,但在某些情况下也会制动。 我的功能:
void removeComments(char* input, char* output)
{
FILE* in = fopen(input,"r");
FILE* out = fopen(ouput,"w");
char c;
while((c = fgetc(in)) != EOF)
{
if(c == '/')
{
c = fgetc(in);
if(c == '/')
{
while((c = fgetc(in)) != '\n');
}
else
{
fputc('/', out);
}
}
else
{
fputc(c,out);
}
}
fclose(in);
fclose(out);
}
但是当我将这样的文件作为输入时:
// Parameters: a, the first integer; b the second integer.
// Returns: the sum.
int add(int a, int b)
{
return a + b; // An inline comment.
}
int sample = sample;
在删除嵌入式注释时,由于某种原因它无法到达'\ n'并提供输出:
int add(int a, int b)
{
return a + b; }
int sample = sample;
[编辑] 感谢您的帮助!它适用于我发布的情况,但在另一个情况下会刹车。 当前代码:
FILE* in = fopen(input,"r");
FILE* out = fopen(output,"w");
if (in == NULL) {
printf("cannot read %s\n", input);
return; /* change signature to return 0 ? */
}
if (out == NULL) {
printf("cannot write in %s\n", output);
return; /* change signature to return 0 ? */
}
int c;
int startline = 1;
while((c = fgetc(in)) != EOF)
{
if(c == '/')
{
c = fgetc(in);
if(c == '/')
{
while((c = fgetc(in)) != '\n')
{
if (c == EOF) {
fclose(in);
fclose(out);
return; /* change signature to return 1 ? */
}
}
if (! startline)
fputc('\n', out);
startline = 1;
}
else if (c == EOF)
break;
else {
fputc('/', out);
startline = 0;
}
}
else
{
fputc(c,out);
startline = (c == '\n');
}
}
fclose(in);
fclose(out);
当文件包含除法时,第二个变量消失。 示例:
int divide(int a, int b)
{
return a/b;
}
它回馈:
int divide(int a, int b)
{
return a/;
}
答案 0 :(得分:3)
之后
Inspector Name
您需要一个while((c = fgetc(in)) != '\n');
其他说明:
在
fputc('\n', out);
c 必须是 int 才能管理EOF
只是拼写错误:输出必须是输出才能编译
读完“ /”后,EOF管理不佳
您错过了检查 fopen
的结果提案:
char c;
while((c = fgetc(in)) != EOF)
正如Tormund Giantsbane在评论中所说,最好完全删除仅包含注释的行(从第一列开始的注释),新提案可以做到这一点:
#include <stdio.h>
void removeComments(char* input, char* output)
{
FILE* in = fopen(input,"r");
FILE* out = fopen(output,"w");
if (in == NULL) {
printf("cannot read %s\n", input);
return; /* change signature to return 0 ? */
}
if (out == NULL) {
printf("cannot write in %s\n", output);
return; /* change signature to return 0 ? */
}
int c;
while((c = fgetc(in)) != EOF)
{
if(c == '/')
{
c = fgetc(in);
if(c == '/')
{
while((c = fgetc(in)) != '\n')
{
if (c == EOF) {
fclose(in);
fclose(out);
return; /* change signature to return 1 ? */
}
}
fputc('\n', out);
}
else if (c == EOF) {
fputc('/', out);
break;
}
else
fputc('/', out);
fputc(c, out);
}
else
{
fputc(c,out);
}
}
fclose(in);
fclose(out);
/* change signature to return 1 ? */
}
int main(int argc, char ** argv)
{
removeComments(argv[1], argv[2]);
}
编译和执行:
#include <stdio.h>
void removeComments(char* input, char* output)
{
FILE* in = fopen(input,"r");
FILE* out = fopen(output,"w");
if (in == NULL) {
printf("cannot read %s\n", input);
return; /* change signature to return 0 ? */
}
if (out == NULL) {
printf("cannot write in %s\n", output);
return; /* change signature to return 0 ? */
}
int c;
int startline = 1;
while((c = fgetc(in)) != EOF)
{
if(c == '/')
{
c = fgetc(in);
if(c == '/')
{
while((c = fgetc(in)) != '\n')
{
if (c == EOF) {
fclose(in);
fclose(out);
return; /* change signature to return 1 ? */
}
}
if (! startline)
fputc('\n', out);
startline = 1;
}
else if (c == EOF) {
fputc('/', out);
break;
}
else {
fputc('/', out);
fputc(c, out);
startline = 0;
}
}
else
{
fputc(c,out);
startline = (c == '\n');
}
}
fclose(in);
fclose(out);
/* change signature to return 1 ? */
}
int main(int argc, char ** argv)
{
removeComments(argv[1], argv[2]);
}
正如DavidC所说。在注释中,如果//放在字符串中,结果将不是预期的结果,即使是非法字符(我的意思是'//'也不得更改)也是如此,C注释呢(/ * .. // ... * /)等
答案 1 :(得分:2)
在删除嵌入式注释时,由于某种原因它无法到达“ \ n”
否,如果在嵌入式注释的末尾无法到达或看不到换行符,则该程序可能会消耗掉文件的其余全部内容。它实际上无法执行的操作是将这样的换行符写入到输出中。
考虑您的注释代码:
while((c = fgetc(in)) != '\n');
读取换行符时,该循环终止。此时,已经被读取的换行符无法再次从输入中读取,因此您的常规读取/写入规定将无法对其进行处理。如果要保留这些换行符,则需要在注释处理分支中打印它们。
其他说明:
fgetc
返回一个int
,而不是char
,并且您需要这样处理它以便能够正确检测文件结尾。 / p>
如果输入的结尾处没有换行符终止,则您的程序将进入无限循环。这种来源在技术上是不合格的,但是即使如此,您也应该处理它。