| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1602 人关注过本帖
标题:求大佬帮忙看看我的程序算法出了什么问题
只看楼主 加入收藏
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
结帖率:83.33%
收藏
 问题点数:0 回复次数:8 
求大佬帮忙看看我的程序算法出了什么问题
题目是编写一个打开两个文件的程序,让程序打印第一个文件的第一行、第二个文件的第一行、第一个文件的第二行、第二个文件的第二行,依此类推,直到打印完行数较多的文件的最后一行。
这是我编写的程序:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#define LEN 256

int main(void)
{
    FILE *fp1, *fp2;
    char name1[LEN], name2[LEN];
    char ch1, ch2;
    int i = 1;

   

    puts("请输入第一个文件名:");
    gets(name1);
    if((fp1 = fopen(name1, "r")) == NULL)
    {
        fprintf(stderr, "不能打开文件%s\n", name1);
        exit(EXIT_FAILURE);
    }
    puts("请输入第二个文件名:");
    gets(name2);
    if((fp2 = fopen(name2, "r")) == NULL)
    {
        fprintf(stderr, "不能打开文件%s\n", name2);
        exit(EXIT_FAILURE);
    }
    while((ch1 = getc(fp1)) != EOF || (ch2 = getc(fp2)) != EOF)
    {
        printf("第%d行\n", i++);
        while(ch1 != EOF && ch1 != '\n')
        {
            putchar(ch1);
            ch1 = getc(fp1);
        }
        if(ch1 != EOF)
        {
            putchar('\n');
        }
        while(ch2 != EOF && ch2 != '\n')
        {
            putchar(ch2);
            ch2 = getc(fp2);
        }
        if(ch2 != EOF)
        {
            putchar('\n');
        }       

    }
    if(fclose(fp1) != 0)
        printf("不能关闭文件%s", name1);
    if(fclose(fp2) != 0)
        printf("不能关闭文件%s", name2);   

   

    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册

程序运行是这样的:

我把ch1=getc(fp1) 放到最外层的while循环里,但是程序输出却是打印第二个文件的第一行,然后全部打印了第一个文件的每一行和一个空行,再全部打印第二个文件。
这是照答案修改的代码
搜索更多相关主题的帖子: 文件 打印 一行 while EOF 
2018-09-07 16:34
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
程序代码:
#include <stdio.h>
#include <stdlib.h>
#define LEN 256

int main(void)
{
    FILE *fp1, *fp2;
    char name1[LEN], name2[LEN];
    char ch1, ch2;
    int i = 1;

   

    puts("请输入第一个文件名:");
    gets(name1);
    if((fp1 = fopen(name1, "r")) == NULL)
    {
        fprintf(stderr, "不能打开文件%s\n", name1);
        exit(EXIT_FAILURE);
    }
    puts("请输入第二个文件名:");
    gets(name2);
    if((fp2 = fopen(name2, "r")) == NULL)
    {
        fprintf(stderr, "不能打开文件%s\n", name2);
        exit(EXIT_FAILURE);
    }
    ch1 = getc(fp1);
    ch2 = getc(fp2);
    while(ch1 != EOF || ch2 != EOF)
    {
        printf("第%d行\n", i++);
        while(ch1 != EOF && ch1 != '\n')
        {
            putchar(ch1);
            ch1 = getc(fp1);
        }
        if(ch1 != EOF)
        {
            putchar('\n');
            ch1 = getc(fp1);
        }
        while(ch2 != EOF && ch2 != '\n')
        {
            putchar(ch2);
            ch2 = getc(fp2);
        }
        if(ch2 != EOF)
        {
            putchar('\n');
            ch2 = getc(fp2);
        }       

    }
    if(fclose(fp1) != 0)
        printf("不能关闭文件%s", name1);
    if(fclose(fp2) != 0)
        printf("不能关闭文件%s", name2);   

   

    return 0;
}
2018-09-07 16:36
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
这是正确的输出
图片附件: 游客没有浏览图片的权限,请 登录注册


我的疑问是,为什么不能省去if循环里的ch1=getc(fp1),而把ch1=getc(fp1)放在while循环的括号里?这样做有什么算法错误?
2018-09-07 16:37
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
我的程序错误的输出
图片附件: 游客没有浏览图片的权限,请 登录注册

2018-09-07 16:39
Mr_doge
Rank: 5Rank: 5
等 级:贵宾
威 望:10
帖 子:159
专家分:385
注 册:2018-6-28
收藏
得分:0 
是我的问题,没看清楚LZ的问题
LZ的代码出现异常行为,和LZ将if内的ch2 = getc(fp2);放入至外部while判断之中是有关系的
原因如下,首先
while((ch1 = getc(fp1)) != EOF || (ch2 = getc(fp2)) != EOF)
这是一个 或(or)判断,第一次进行判断,ch1和ch2都读入数据(初始化),然后进行逻辑判断,判断ch1!=EOF通过,执行循环内语句,此时,ch1和ch2都正常读入第一个字符(非\n非EOF),然后循环体内都正常运行,直到一行打印完毕,此时,ch1内存储的是\n
进入第二个大周期(第二行),ch1被赋值覆盖,\n替换为第二行首字符,ch1!=EOF检定通过,执行循环体内容(没错,执行循环体内容!)此时,ch2依旧是\n
然后第二行的fp1正常打印,fp2因为一直是\n,一直打印\n
一直到打印玩fp1的文件内容,ch1!=EOF为假,覆写并判断ch2,(此时ch2='\n'被变更),判断通过,执行循环体内容,由于ch1=EOF,仅执行fp2的循环,如此往复直至打印完毕fp2

错误原因:关系运算符||的判断从左至右,当左值判断为真,则检定通过,不会执行右值检定,导致ch2的\n未更新

[此贴子已经被作者于2018-9-11 12:34编辑过]

2018-09-10 09:03
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
回复 4楼 心空之上
你说的这段语句是答案的正确语句,这段语句先执行while循环,遇到'\n'和EOF退出while循环。再进入if循环,因为上个循环的结束可能是遇到'\n'或者EOF,if循环是解决了遇到'\n'的情况,如果遇到'\n',就给ch1重新赋值,再回到外层的while循环,然后打印下一行语句。
我的错误的地方是最外层的while循环那里while((ch1 = getc(fp1)) != EOF && (ch2 = getc(fp2))!=EOF),在while循环中给ch1赋值,程序就出错了
2018-09-10 19:44
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
回复 5楼 Mr_doge
你说的这段语句是答案的正确语句,这段语句先执行while循环,遇到'\n'和EOF退出while循环。再进入if循环,因为上个循环的结束可能是遇到'\n'或者EOF,if循环是解决了遇到'\n'的情况,如果遇到'\n',就给ch1重新赋值,再回到外层的while循环,然后打印下一行语句。
我的错误的地方是最外层的while循环那里while((ch1 = getc(fp1)) != EOF && (ch2 = getc(fp2))!=EOF),在while循环中给ch1赋值,程序就出错了
2018-09-10 20:58
Mr_doge
Rank: 5Rank: 5
等 级:贵宾
威 望:10
帖 子:159
专家分:385
注 册:2018-6-28
收藏
得分:0 
回复 7楼 心空之上
已更正
另外,将未初始化的变量用作判断对比条件并不是好习惯,因此个人更推荐原代码,LZ的代码一定要在现基础上变更的话,只能将ch2按照原代码的方式设置。

回楼下,并非是while循环判断内不能进行读入数据和初始化,只是本例是属于文件字符读入并且带有关系判断,不适合将赋值置入循环判断条件罢了,实际上更简洁一直都是C所提倡的。

[此贴子已经被作者于2018-9-12 12:48编辑过]

2018-09-11 12:31
心空之上
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2018-5-29
收藏
得分:0 
回复 8楼 Mr_doge
非常感谢啊,已经明白自己问题所在了。本人还是新手一枚,因为书上打印字符都是把ch在while循环的括号里进行的,这次按照书上这样做了,没有考虑到||的逻辑判断,以后会改正的。
2018-09-11 22:23
快速回复:求大佬帮忙看看我的程序算法出了什么问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.037576 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved