请教C语言写的简单字典程序的问题

MAYANGBIN_ 2016-11-28 09:17:05
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#pragma warning(disable:4996)

typedef struct
{
char *content;//用于记录txt奇数行内容首地址
char *translate;//用于记录txt偶数行内容首地址
} word;

int opencasio(word **str, const char* filename, int *num)//打开文件并读取内容 返回词条数num
{
FILE *p = fopen(filename, "r");
if (p)
{
char buf[1024] = { 0 };
int i = 0;//记录字典的单词数
int l = 0;
while (!feof(p))
{
i++;

*str = (word *)realloc(*str, i*sizeof(word));//根据单词数分配内存
memset(*str + i - 1, 0, sizeof(word));//清空新分配内存的结构内容
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), p);
l = strlen(buf);
(*str)[i - 1].content = (char *)calloc(l, sizeof(char));//根据txt文件行的大小分配content大小 变l
strcpy((*str)[i - 1].content, &buf[1]);//将txt文件内容导入结构数组

memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), p);
l = strlen(buf);
(*str)[i - 1].translate = (char *)calloc(l, sizeof(char));//根据txt文件行的大小分配translate大小
strcpy((*str)[i - 1].translate, &buf[6]);//将txt文件内容导入结构数组

//printf("w[%d].content = %s\n", i, (*str-1)[i].content);
//printf("w[%d].translate = %s\n", i, (*str-1)[i].translate);
}
*num = i;
fclose(p);
return 0;//0成功打开文件
}
else
return 1;//未能打开文件
}

int lookup(const char *wantcontent, char *wanttranslate, int num, word *str)//查单词
{
int i;
for (i = 0; i < num; i++)
{
if (0 == strncmp(str[i].content, wantcontent, strlen(wantcontent))) //必须strncmp,不然最后有个\n!!!太坑
{
strcpy(wanttranslate, str[i].translate);
return 0;
}
}
return 1;//0查到相关词条 1未查到
}


int freeword(word *str, int num)//释放分配的内存
{
int i;
for (i = 0; i < num; i++)
{
free(str[i].content);
free(str[i].translate);
}
free(str);
return 0;
}

int main(int argc, char *args[])//int argc,char *args[]
{
word *str = NULL;
int num = 0;

if (argc < 2)
printf("USAGE: %s filename\n", args[0]);

long open1 = 0L;
long open2 = 0L;
open1 = clock();

if (0 == opencasio(&str, args[1], &num))
{
open2 = clock();
printf("open_dict used %ld ms\n", open2 - open1);
}
else
{
printf("CAN NOT OPEN FILE!\n");
return 0;
}


char wantcontent[1024] = { 0 };
char wanttranslate[1024] = { 0 };
while (1)
{
memset(wantcontent, 0, sizeof(wantcontent));
memset(wanttranslate, 0, sizeof(wantcontent));
scanf("%s", wantcontent);
if (0 == strcmp("BIUBIUBIU", wantcontent))//输入BIUBIUBIU关闭字典为什么会报错
break;

if (0 == lookup(wantcontent, wanttranslate, num, str))
printf("%s\n", wanttranslate);
else
printf("NOT FOUND!\n");
}

long free1 = 0L;
freeword(str, num);
long free2 = 0L;
printf("open_dict used %ld ms\n", free2 - free1);

return 0;
}

字典是以下格式的txt文件:
#a
Trans:art. 一;字母A
#a.m.
Trans:n. 上午
#a/c
Trans:n. 往来帐户@往来:come - and - go; contact; intercourse@n. 往来帐户
#aardvark
Trans:n. 土猪

这是我用C语言写的一个字典程序用来查奇数行的内容显示偶数行的内容
这个程序在字典的txt文件很小的时候可以很顺利地运行
但是在字典的txt文件很大的时候查询没问题,但在输入BIUBIUBIU退出或者运行代码不加txt文件名的时候DOS会报错卡死


第一张是4M的txt,第二张就是只有四个单词的txt
我是C语言新手,最近刚自学的,麻烦大家帮我看一下是代码哪里有问题?要怎么修改?谢谢大家!
求各位大大帮忙!告诉我一下我应该怎么修改!
...全文
575 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
小灸舞 版主 2016-11-30
  • 打赏
  • 举报
回复
很明显是你申请的堆空间被越界写入了,导致堆被破坏,所以析构时出错。
赵4老师 2016-11-29
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
paschen 2016-11-29
  • 打赏
  • 举报
回复
点击重试,然后点击中断,通过调用堆栈定位到相关代码,观察分析原因,必要时可单步跟踪程序运行 从提示看,很可能是堆越界了
邂逅模拟卷 2016-11-28
  • 打赏
  • 举报
回复
刚自学就那么厉害啦,膜

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧