[英]C program that removes comments
這是我的第一次發布,因此我對格式不佳或任何不合理的問題表示歉意。
因此,我已經在“刪除評論”程序上工作了一段時間,並取得了進展,但進展很小。 我是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;
}
問題是我無法找出一種方法來設置條件,該條件會在出現評論但未關閉的情況下(例如(一些/ *瘋狂的東西)打印出錯誤消息
另一個問題是我似乎找不到運行我的程序並輸入文本文件時忽略*的bug,因此當我輸入時:
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
我找不到解決這兩個問題的方法。 教授通過定義不同的狀態提出了一種不同的編寫程序的方式,但是當我嘗試這樣做時,甚至更加令人困惑。
您的描述着重於對流進行操作和對緩沖區進行操作之間的區別。 在C和Java中,這兩種技術都是可行的。
在這里,您的任務是在流情況下完成任務,即您不能“向前看”,也不能“向后寫”-您所能做的就是檢索下一個字符,在合適的情況下更新一些變量,然后決定是否輸出該字符。
這稱為狀態機 ; 您的主循環將讀取一個字符,然后根據變量所處的狀態采取不同的操作。
要開始使用,您至少需要存儲以下內容:
/
。 例如,如果設置了后一個狀態,並且得到一個'*'
則可以設置前一個狀態(並重置后一個狀態)。
好吧,解決此類問題的常用方法是制作FSM 。 因此,只需確定狀態數並定義由於當前狀態而導致的每個下一個字母將如何影響狀態。 有點像
//#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();
}
此代碼僅刪除/ ** /。 編寫更大的圖表並完成代碼。
#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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.