这是我第一次发帖,所以我为糟糕的格式或任何不合理的问题道歉。
所以我一直在研究"删除评论"程序已经有一段时间了,取得了很大的进步。我是C的新手,所以我用一些基本的功能和技巧来写它。代码的输入文件不需要读取任何函数,而是使用<在终端。
我使用的文本文件包含以下内容:
some/* crazy */stuff
some/* crazy */ stuff
some/*crazy /*crazy*/*/stuff
"some /* crazy */ stuff "
some/* "crazy" */ stuff
some/* crazy stuff
测试不同的评论格式。 我到目前为止的代码是:
#include <stdio.h>
#define IN_COMMENT 1
int main(int argc, char **argv)
{
int c;
while ((c=getchar())!=EOF)
{
if(c=='/'&&getchar()=='*')
{
while(c!='*' && getchar()!='/')
{
c = " ";
c= getchar();
}
}
if(c=='"')
{
c=getchar();
while(c!='"')
{
putchar(c);
c=getchar();
}
putchar(c);
}
}
putchar(c);
printf("done.\n");
return 0;
}
问题是我无法找到一种方法来设置一个条件,当条件开始但是从未关闭时,会打印出错误消息,例如(某些/ *疯狂的东西)< / p>
另一个问题是我似乎无法找到当我运行程序并输入文本文件时省略*的错误,所以当我输入时:
some/* crazy */stuff
some/* crazy */ stuff
some/*crazy /*crazy*/*/stuff
"some /* crazy */ stuff "
some/* "crazy" */ stuff
我最终获得以下内容: 一些*东西
some* stuff
some**/tuff
"some /* crazy */ stuff "
some* stuff
我无法找到解决这两个问题的方法。教授通过定义不同的状态提出了一种不同的编写程序的方法,但是当我尝试它时,它更令人困惑。
答案 0 :(得分:0)
您的描述侧重于在流上操作和在缓冲区上操作之间的区别。在C和Java中,任何一种技术都是可行的。
在这里,你的任务是在流动的情况下完成工作,即你不能&#34;展望未来&#34;你不能倒退#34; - 您所能做的就是检索下一个字符,在适当的时候更新一些变量,然后决定是否输出该字符。
这称为状态机;你的主循环将读取一个字符,然后根据变量的状态采取不同的操作。
为了帮助您入门,您需要至少存储以下内容:
/
。例如,如果设置了后一种状态并且您得到'*'
,那么您将设置前一种状态(并重置后者)。
答案 1 :(得分:0)
通常,解决此类问题的方法是FSM。因此,由于当前状态,只需创建多个状态并确定每个下一个字母将如何影响状态。像Smth一样
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//#include <conio.h>
#include <string.h>
typedef enum states {
CODE,
HASH_START,
STAR_END,
COMMENT
} states;
void main() {
FILE *input = NULL;
char c;
states state;
state = CODE;
input = fopen("C:/c/code.txt", "r");
if (input == NULL) {
exit(EXIT_FAILURE);
}
while (fscanf(input, "%c", &c) == 1) {
switch (c) {
case '/' :
switch (state) {
case CODE:
state = HASH_START;
break;
case STAR_END:
//a bit ugly here, but require less states. You can omit read next
//if use more states
fscanf(input, "%c", &c);
state = CODE;
break;
}
break;
case '*' :
switch (state) {
case HASH_START:
state = COMMENT;
break;
case COMMENT:
state = STAR_END;
break;
}
break;
default:
if (state == HASH_START) {
state = CODE;
}
}
if (state == CODE) {
printf("%c", c);
}
}
//_getch();
}
此代码仅删除/ ** /。写出更大的图表和完整的代码。
答案 2 :(得分:0)
#include <stdio.h>
#if 0
Description :
To delete a comment by entering the C source from standard input.
// To delete a line break up (newline remain)
/**/ To allow the nest (standard does not allow)
also replaced with a single space(The request by the standard)
#endif
int main(void){
FILE *fp = stdin;
int ch, chn;
int nest_level=0;
#if 0
in_range_comment : /* this */
in_line_comment : //this
in_string : "this"
in_char_constnt : ' '
#endif
enum { none, in_line_comment, in_range_comment, in_string, in_char_constant } status;
status = none;
while(EOF!=(ch=fgetc(fp))){
switch(status){
case in_line_comment :
if(ch == '\n'){
status = none;
putchar(ch);
}
continue;
case in_range_comment :
if(ch == '*'){
chn = fgetc(fp);
if(chn == '/'){
if(--nest_level == 0){
status = none;
putchar(' ');
}
continue;
}
ungetc(chn, fp);
} else if(ch == '/'){
chn = fgetc(fp);
if(chn == '*'){
++nest_level;
continue;
}
ungetc(chn, fp);
}
continue;
case in_string :
if(ch == '\\'){
putchar(ch);
chn = fgetc(fp);
if(chn == '"'){
putchar(chn);
continue;
}
ungetc(chn, fp);
} else {
if(ch == '"')
status = none;
putchar(ch);
}
continue;
case in_char_constant :
if(ch == '\\'){
putchar(ch);
chn = fgetc(fp);
if(chn == '\''){
putchar(chn);
continue;
}
ungetc(chn, fp);
} else {
if(ch == '\'')
status = none;
putchar(ch);
}
continue;
case none :
switch(ch){
case '/':
if('/' == (chn = fgetc(fp))){
status = in_line_comment;
continue;
} else if('*' == chn){
status = in_range_comment;
++nest_level;
continue;
} else
ungetc(chn, fp);
putchar(ch);
break;
case '"':
status = in_string;
putchar(ch);
break;
case '\'':
status = in_char_constant;
putchar(ch);
break;
default:
putchar(ch);
}
}
}
return 0;
}