首页 > 解决方案 > 我需要在程序中解决这两个问题。根据输入,我需要修复代码以产生所需的输出

问题描述

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void handle(FILE *np)// this is to handle newline characters
{
    putc('\n', np);

}
/* skip a C multi-line comment, return the last byte read or EOF */
int m_cmnt(FILE *fp, int *lineno_p) {
FILE *np = stdout;
int prev, ch, replacement = ' ';
for (prev = 0; (ch = getc(fp)) != EOF; prev = ch) {
    if (prev == '\\' && ch == 'n') {
        replacement = '\n';
        ++*lineno_p;
        }
    if (prev == '*' && ch == '/')
        return replacement;
    }

return EOF;
}

int main(int argc, char *argv[]) {
FILE *fp = stdin, *np = stdout;
int ch,prev;
bool String = 0;
const char *filename = "<stdin>";
int lineno = 1;

fp = fopen(filename, "r");
np = fopen(argv[2], "w");

if (argc > 1) {
    if ((fp = fopen(filename = argv[1], "r")) == NULL) {
        fprintf(stderr, "Cannot open input file %s: \n",
                filename);
        exit(EXIT_FAILURE);
    }
}
if (argc > 2) {
    if ((np = fopen(argv[2], "w")) == NULL) {
        fprintf(stderr, "Cannot open output file %s: \n",
                argv[2]);
        exit(EXIT_FAILURE);
    }
}

while ((ch = getc(fp)) != EOF) {
    if (ch == '\n')
        lineno++;
    /* file pointer currently not inside a string */
    if (!String) {
        if (ch == '/') {
            ch = getc(fp);
            if (ch == '\n')
                lineno++;
            if (ch == '*') {
                int startline = lineno;
                ch = m_cmnt(fp, &lineno);
                if (ch == EOF) {
                    fprintf(stderr, "%s:%d: error: unterminated comment started on line %d\n",
                            filename, lineno, startline);
                            exit(EXIT_FAILURE);
                    break;
                }
                putc(ch, np);
            } else {
                putc('/', np);
                putc(ch, np);
            }
        }
         else if ( ch=='\\')/*to handle newline character*/
            {
                prev=ch ;
                ch= getc(fp) ;
                switch(ch)
                {
                    case 'n'  :
                                handle(np);
                                 break ;
                    /*default   :
                                 putc(prev , np) ;
                                 putc(ch , np) ;
                                 break ;*/
                }
            }
        else {
            putc(ch, np);
        }
    } else {
        putc(ch, np);
    }
    if (ch == '"' || ch == '\'')
        String = !String;
}
fclose(fp);
fclose(np);
//remove(arr[1]);
//rename("temp.txt", arr[1]);
return EXIT_SUCCESS;
}

我已经在这个项目上工作了将近一个多星期了。我在这个网站上问了很多问题来帮助我得到想要的结果。这个程序的基础是从源文件中删除多行注释并将其余的写入一些输出文件。它还需要忽略字符串文字或字符文字(如转义字符)中的任何内容。 现在我已经完成了它,但我仍然需要实现如下所示的这两个输出

INPUT1 = //*SOMECOMMENT*/  
OUTPUT1 = /
INPUT2 = "this \"test"/*test*/
OUTOUT2 = "this \"test"

当前(错误)输出如下所示

INPUT1 = //*SOMECOMMENT*/  
OUTPUT1 = //*SOMECOMMENT*/    This is wrong.
INPUT2 = "this \"test"/*test*/
OUTOUT2 = "this \"test"/*test*/   This is also wrong.

该程序不适用于注释出现在正斜杠(/)之后的情况,并且程序的第二个失败是它不忽略字符串或字符文字中的转义字符。我需要解决这两个问题。

标签: c

解决方案


如果您的问题是您想要读取字符输入流,将该流划分为标记,然后只发出这些标记的子集,我认为Lex正是您正在寻找的工具。

如果我正确理解您的评论,那么您尝试读取和转换的文件本身就是 C 代码。因此,您需要建立 C 语言规则的 Lex 定义。

快速搜索发现了这个 ANSI C 语法的 Lex 规范。我不能保证它的准确性或谈论它的许可。乍一看似乎只支持C89。但这可能足以为您指明正确的方向。


推荐阅读