自己写的C语言,求更正。先给30分,答案好追加到100分。

#include<stdio.h>
#include<ctype.h>
struct adnum
{
char ad[1000]; /*存储地址和号码*/
char num[12];

} dz[10000];

void main()
{
int i,j,k=0;
FILE*yw , *dw, *nw;
char fyw[50],fdw[50],fnw[50],put[100000];

printf("请输入原文本路径:\n");
scanf("%s",fyw);

printf("请输入地址路径:\n");
scanf("%s",fdw);

printf("请输入号码路径:\n");
scanf("%s",fnw);

yw=fopen(fyw,"r");
dw=fopen(fdw,"w");
nw=fopen(fnw,"w");

fseek(yw,0L,SEEK_END); /* 获取原文本的字节大小 */
int size=ftell(yw);

rewind(yw);

for(i=0;i<size;i++)
fread(&put[i],1,1,yw); /* 把原文本的数据转录到数组put */

for(i=0;i<size;i++) /* 把数组put里边的号码提取出来,转存到结构体数组dz.num里边。 */
{
if(put[i]==49&&put[i+1]<58&&put[i+1]>46&&put[i+2]<58&&put[i+2]>46&&put[i+3]<58&&put[i+3]>46&&put[i+4]<58&&put[i+4]>46
&&put[i+5]<58&&put[i+5]>46&&put[i+6]<58&&put[i+6]>46&&put[i+7]<58&&put[i+7]>46&&put[i+8]<58&&put[i+8]>46&&put[i+9]<58&&put[i+9]>46&&put[i+10]<58&&put[i+10]>46)
{ for(j=0;j<11;j++)
dz[k].num[j]=put[i+j];
dz[k].num[11]='\n';
k++;
}
}

for(i=0;i<k;i++)
fputs(dz[i].num,nw);

for(i=1;i<size;i++) /*把数组put里边的地址提取出来,转存到结构体数组dz.ad里边。 */
if(put[i-1]==64)
{
for(j=0;put[j+i]!=44;j++)
dz[k].ad[j]=put[i+j];
dz[k].num[j+1]='\n';
k++;
}
for(i=0;i<k;i++)
fputs(dz[i].ad,dw);

fclose(dw);
fclose(nw);
fclose(yw);

}
第一个问题是能够正常的获取手机号码,地址也能获取,问题是获取完后,最后的一个地址后边是一大串乱码,怎么改正?
第二个问题是,判断是不是手机号码的if语句太长了。。。自己没想到好的办法啊,能不能想办法改正一下。
第三个问题是,如何直接将地址和号码直接弄到一个文件里?格式大概如下:
地址1,号码1
地址2,号码2

原文件

输出的地址文件

输出的号码文件
红旗街百脑汇后,2室1厅,2/6,58.5 ,私
人产权,40万元,电话:15004318950。
建设街西安大路,2室1厅,4/7,南北向,
59.02 ,私人产权,43万元,电话:
15330608678。

上面是要处理的文本,如何把地址和电话号码提取出来,我的想法是句号和逗号中间是地址,例如”电话:15004318950。建设街西安大路,“,就用if语句来判断。然后。。。不知道中文的句号和逗号的ASCII码值,就把句号替换成了@,把中文的逗号替换成了英文的。有没有更好的方法解决这个问题?即不用替换逗号,句号,冒号。这个是附加问题了,答不答无所谓。

问题一, 在取地址的程序中, 头尾的判断不一致. 按照图片中的片段, 末尾应是'@', 但是程序却当成起头.

除了末尾会有乱码外, 起头第一笔地址, 应该也会有遗漏的问题.


问题二, 可以从(1)写法(2)呼叫函式来改善. C语言是结构化语言, 程序中没有用到函式, 其实并没有发挥出效用.

但是要使用其他的方式, 对於Pointer及Array的使用要更清楚, 才不易错误.

(1)写法

    if( put[i]==49 && put[i+1]<58 &&
        put[i+1]>46 && put[i+2]<58 &&
        put[i+2]>46 && put[i+3]<58 &&
        put[i+3]>46 && put[i+4]<58 &&
        put[i+4]>46 && put[i+5]<58 &&
        put[i+5]>46 && put[i+6]<58 &&
        put[i+6]>46 && put[i+7]<58 &&
        put[i+7]>46 && put[i+8]<58 &&
        put[i+8]>46 && put[i+9]<58 &&
        put[i+9]>46 && put[i+10]<58 &&
        put[i+10]>46 )
    {
        //....
    }

(2)呼叫函式

   if( is_string_phone_num(&put[i]) == true ) //替代一大串
    {
        //....
    }
    //在main外撰写函式, 供main呼叫
    unsigned char is_string_phone_num(unsigned char *ptr)
    {
        return ( put[i]==49 && put[i+1]<58 &&
                 put[i+1]>46 && put[i+2]<58 &&
                 put[i+2]>46 && put[i+3]<58 &&
                 put[i+3]>46 && put[i+4]<58 &&
                 put[i+4]>46 && put[i+5]<58 &&
                 put[i+5]>46 && put[i+6]<58 &&
                 put[i+6]>46 && put[i+7]<58 &&
                 put[i+7]>46 && put[i+8]<58 &&
                 put[i+8]>46 && put[i+9]<58 &&
                 put[i+9]>46 && put[i+10]<58 &&
                 put[i+10]>46);
    }

ps. 先改善程序的可读性, 若是想改善写法, 再来另外处理函式内容.


问题三, 其实地址跟电话, 可以在第一次循序读档时一起读取, 当前因为分别采用两种不同的判断方式, 导致无法一起处理. 先从文档架构的固定顺序上来看, 可以先这样假设.(实际上并不太好, 但是从原有架构上, 可以先这样逐步演化, 再慢慢调整解法)

    for(i=0;i<size;i++)
    {
        i = find_and_get_address(&put[i]);
        // return new index that after address
        
        i = find_and get_phone_number(&put[i]);
        // return new index that after phone number
        
        write_address_and_phone_number_to_file();
        //考量末尾长度, 可以设定一个常数(基本四个字节没问题),
        //在for的size判断, 预先少几个字节, 避免i == (size-1) 情况.
    }


所有的程序问题, 都是先拆解成小方块, 再逐一解决单一问题, 如此将容易许多了.


关於中文, 实际上每一个字都是双字节, 处理上会稍稍麻烦一些, 但是依照拆解原则, 先写成一个函式, 再来单单思考双字节判断问题, 就会感觉容易了. 希望以上会有帮助.

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-09-28
前方是苦海,所以不打算继续误导楼主走下去。

我根据的你的描述,略微发表一下自己的看法,你要是觉得有用,给个采纳,谢谢!

①,先确定输入文件会是多大,你的fseek可以获取文件大小,这个时候,malloc动态开辟内存来获取空间,如果获取动态内存失败,报错,提示需要手动缩减原文件。

②,能借助外部工具格式化原文件是最好的,第一:格式化为ANSI编码;第二:你程序需要判断英文逗号,那么就把中文的逗号也格式化为英文的。你的地址需要有分割标记,那么就把地址前的固定字符替换成你规定的字符。

如果可以,你还可以替换"电话"这类关键词为一个固定符号。

经过简单处理,就成为了一个规定的原文件。

那么算法将是简单的,读取原文件字符串,扫描字符串,用strstr或者strch(区别在于strstr是针对字符串,而strch是针对一个字符)去扫描,找到你设定的关键字符或字符串,然后读取对应值,比如设原文件读取的字符串为file_str
char * ptel = file_str;
while( (ptel = strstr(ptel, "电话") ) != NULL)
{
这里ptel就是指向了“电话”,你再自己写代码去读取电话后面的具体值

另外,判断一个字符是否为数字,可以用库函数isdigit,具体查一下,还有个strtol可以转换数字字符串为数值,并且返回最后一个数字字符的指针位置,而你可以读取整个指针位置去判断是否合法
}本回答被网友采纳
相似回答