鱼C论坛

 找回密码
 立即注册
查看: 1303|回复: 4

[已解决]求做一道oj题

[复制链接]
发表于 2020-3-24 12:35:15 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 nameisnothing 于 2020-3-24 17:51 编辑

学校oj上的一道题目,卡了很久了,谁能帮帮我。我目前只会最基础的c语言,没学数据结构和算法,文件操作只会最简单的fopen,putc,fseek等函数,会用的函数库也只有stdio.h,string.h这些。所以各位大哥尽量用基础方法解决,让我这个初学者能看得懂。
问题 C: 实验12_4_过滤注释
时间限制: 1 Sec  内存限制: 128 MB
题目描述
C语言的注释分为两种,第一种:在一行源代码中“//”后的内容为注释内容。第二种:“/*”与“*/”之间的内容为注释内容。第三种:程序中只出现了“/*”,没有“*/”与之对应,那么将“/*”后的全部内容都要过滤掉。注意,只要是注释内容,那么注释内容中的字符应该全部忽略,即不起任何的作用。例如“/*”与“*/”之间如果再有“//”,那么“//”不应起作用;如果“//”再有“/*”,那么“/*”也不应起作用。
你的任务是先打开一个名字为dict.dic的文本文件,该文件中前5行每行为1个整数,从第6行开始为5段C语言的源代码。那5个数字代表这5段源代码结束的行数,比如如果第一行的整数为20,第二行的整数为60,则表示从第6行到第20为第一段代码,从第21行到第60为第二段代码。然后根据输入要求将源代码中所有注释过滤掉。
在本过滤注释系统中,你可以忽略源文件中双引号导致“//”、“/*”、“*/”失去作用的情况,即只要“//”、“/*”、“*/”不是注释内容,在任何情况下都起作用。
输入
只可能是1,2,3,4,5之一
输出
输入为1则输出第一段代码过滤后的结果,输入为2则输出第二段代码过滤后的结果,依此类推。
样例输入
1
样例输出
如果第一段代码是这样:


#include<stdio.h>

int main()
{
        int a = 10 , b = 2 , c ;
        c = a / b ; //I just want to test '/'
        printf("I love programming C.\n") ; //"printf" is a useful function /*
        printf("I hope you love it too!\n") ;
        /*
        //C is not always hard , if you love it , it will not treat you rough.
        */
        return 0 ;
}

则输出是这样:


#include<stdio.h>

int main()
{
        int a = 10 , b = 2 , c ;
        c = a / b ;
        printf("I love programming C.\n") ;
        printf("I hope you love it too!\n") ;

        return 0 ;
}
最佳答案
2020-3-24 12:35:16
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void print(FILE *fp, int sel)
{
    char buff[1024];
    int start = 0;
    int end;
    bool comment = false;
    bool string = false;
    for(int i = 1; i <= 5; ++i) {
        int temp;
        fscanf(fp, "%d", &temp);
        if(i == sel - 1) start = temp + 1;
        if(i == sel) end = temp;
    }
    fgetc(fp);
    if(!start) start = 6;
    for(int i = 6; i < start; ++i)
        fgets(buff, 1024, fp);
    for(int i = start; i <= end; ++i) {
        fgets(buff, 1024, fp);
        for(int j = 0; buff[j]; ++j) {
            if(comment) {
                if(buff[j + 1] && (buff[j] == '*' && buff[j + 1] == '/')) {
                    ++j;
                    comment = false;
                }
            } else if(string) {
                if(buff[j] == '"') string = false;
                printf("%c", buff[j]);
            } else {
                if(buff[j + 1] && (buff[j] == '/' && buff[j + 1] == '/')) {
                    printf("\n");
                    break;
                }
                if(buff[j + 1] && (buff[j] == '/' && buff[j + 1] == '*')) {
                    ++j;
                    comment = true;
                    continue;
                }
                if(buff[j] == '"') string = true;
                printf("%c", buff[j]);
            }
        }
    }
}

int main(void)
{
    int sel;
    FILE *fp = fopen("dict.dic", "r");
    printf("请输入: ");
    scanf("%d", &sel);
    if(sel >= 1 && sel <= 5)
        print(fp, sel);
    fclose(fp);
    return 0;
}

dict.dic
19
60
80
89
103
// 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Free_String(char **mybuf, int num)
{
    if(mybuf == NULL)
        return;
    for(int i = 0; i < num; ++i) {
        free(mybuf[i]);
    }
    free(mybuf);
}
// 2
// 分割字符串
int spitString(const char *mytmp, char c, char ***mybuf, int *num)
{
    if(mytmp == NULL || num == NULL)
        return -1;
    const char *p1 = mytmp;
    int count = 0;

    /* 先扫描一遍字符串,得到子串数量*/
    /* // abcd */
    // /* abcd
    while(p1 = strchr(p1, ','))
    {
        count++;
        p1++;
    }
    ++count;
    char **pp = NULL;
    pp = malloc(count * sizeof(char *));
    if(pp == NULL)
    {
        *mybuf = pp;
        return -2;
    }
    const char *p = mytmp, *q;
    for(int i = 0; i < count; ++i)  // 初始化这些指针  /* abcd */
        pp[i] = NULL;
    for(int i = 0; i < count; ++i) {
        q = strchr(p, c);
        if(!q) q = p + strlen(p);
        pp[i] = malloc(q - p + 1);
        if(!pp[i]) return -3;
        strncpy(pp[i], p, q - p);
        pp[i][q - p] = '\0';
        p = q + 1;
    }
    *mybuf = pp;
    *num = count;
    return 0;
}
// 3
int main(void)
{
    int cls = 0;
    char tmp[100] = {"abcdef,acccd,eeee,aaaa,e3eeee,/* abc */,ssssa,//"};
    char c = ',';
    int num = 0, i;
    char **buf = NULL;
    cls = spitString(tmp, c, &buf, &num);
    if(cls != 0)
    {
        printf("fucn spitString() err: %d\n", cls);
        return cls;
    }
    for(i = 0; i < num; i++)
        printf("%s\n", buf[i]);
    printf("%d\n", num);
    Free_String(buf, num);
    return cls;
}
// 4
/*
#include <stdio.h>

int main(void)
{
        printf("hello world!\n");
        return 0;
}
// 5
#include<stdio.h>

int main()
{
        int a = 10 , b = 2 , c ;
        c = a / b ; //I just want to test '/'
        printf("I love programming C.\n") ; //"printf" is a useful function /*
        printf("I hope you love it too!\n") ;
        /*
        //C is not always hard , if you love it , it will not treat you rough.
        */
        return 0 ;
}

最佳答案

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-24 12:35:16 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void print(FILE *fp, int sel)
{
    char buff[1024];
    int start = 0;
    int end;
    bool comment = false;
    bool string = false;
    for(int i = 1; i <= 5; ++i) {
        int temp;
        fscanf(fp, "%d", &temp);
        if(i == sel - 1) start = temp + 1;
        if(i == sel) end = temp;
    }
    fgetc(fp);
    if(!start) start = 6;
    for(int i = 6; i < start; ++i)
        fgets(buff, 1024, fp);
    for(int i = start; i <= end; ++i) {
        fgets(buff, 1024, fp);
        for(int j = 0; buff[j]; ++j) {
            if(comment) {
                if(buff[j + 1] && (buff[j] == '*' && buff[j + 1] == '/')) {
                    ++j;
                    comment = false;
                }
            } else if(string) {
                if(buff[j] == '"') string = false;
                printf("%c", buff[j]);
            } else {
                if(buff[j + 1] && (buff[j] == '/' && buff[j + 1] == '/')) {
                    printf("\n");
                    break;
                }
                if(buff[j + 1] && (buff[j] == '/' && buff[j + 1] == '*')) {
                    ++j;
                    comment = true;
                    continue;
                }
                if(buff[j] == '"') string = true;
                printf("%c", buff[j]);
            }
        }
    }
}

int main(void)
{
    int sel;
    FILE *fp = fopen("dict.dic", "r");
    printf("请输入: ");
    scanf("%d", &sel);
    if(sel >= 1 && sel <= 5)
        print(fp, sel);
    fclose(fp);
    return 0;
}

dict.dic
19
60
80
89
103
// 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Free_String(char **mybuf, int num)
{
    if(mybuf == NULL)
        return;
    for(int i = 0; i < num; ++i) {
        free(mybuf[i]);
    }
    free(mybuf);
}
// 2
// 分割字符串
int spitString(const char *mytmp, char c, char ***mybuf, int *num)
{
    if(mytmp == NULL || num == NULL)
        return -1;
    const char *p1 = mytmp;
    int count = 0;

    /* 先扫描一遍字符串,得到子串数量*/
    /* // abcd */
    // /* abcd
    while(p1 = strchr(p1, ','))
    {
        count++;
        p1++;
    }
    ++count;
    char **pp = NULL;
    pp = malloc(count * sizeof(char *));
    if(pp == NULL)
    {
        *mybuf = pp;
        return -2;
    }
    const char *p = mytmp, *q;
    for(int i = 0; i < count; ++i)  // 初始化这些指针  /* abcd */
        pp[i] = NULL;
    for(int i = 0; i < count; ++i) {
        q = strchr(p, c);
        if(!q) q = p + strlen(p);
        pp[i] = malloc(q - p + 1);
        if(!pp[i]) return -3;
        strncpy(pp[i], p, q - p);
        pp[i][q - p] = '\0';
        p = q + 1;
    }
    *mybuf = pp;
    *num = count;
    return 0;
}
// 3
int main(void)
{
    int cls = 0;
    char tmp[100] = {"abcdef,acccd,eeee,aaaa,e3eeee,/* abc */,ssssa,//"};
    char c = ',';
    int num = 0, i;
    char **buf = NULL;
    cls = spitString(tmp, c, &buf, &num);
    if(cls != 0)
    {
        printf("fucn spitString() err: %d\n", cls);
        return cls;
    }
    for(i = 0; i < num; i++)
        printf("%s\n", buf[i]);
    printf("%d\n", num);
    Free_String(buf, num);
    return cls;
}
// 4
/*
#include <stdio.h>

int main(void)
{
        printf("hello world!\n");
        return 0;
}
// 5
#include<stdio.h>

int main()
{
        int a = 10 , b = 2 , c ;
        c = a / b ; //I just want to test '/'
        printf("I love programming C.\n") ; //"printf" is a useful function /*
        printf("I hope you love it too!\n") ;
        /*
        //C is not always hard , if you love it , it will not treat you rough.
        */
        return 0 ;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-24 12:47:49 | 显示全部楼层
可能会用到的函数有getc,putc,fopen,fclose,fseek,ftell,fread,fwrite,fgets,fputs,fflush,都在stdio.h中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-24 15:44:57 | 显示全部楼层
能不能提供 dict.dic 文件?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-24 16:55:47 | 显示全部楼层
人造人 发表于 2020-3-24 15:44
能不能提供 dict.dic 文件?

这个是文件是Oj测试用例,我也不知道
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-15 16:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表