| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 870 人关注过本帖
标题:[新手请教]照抄书上的例子,运行结果和书上写的不一样(延迟方法和\r 的问 ...
只看楼主 加入收藏
zig219
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2014-5-29
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:7 
[新手请教]照抄书上的例子,运行结果和书上写的不一样(延迟方法和\r 的问题)
Ivor Horton 的《C语言入门经典》第四版,第四章《循环》中的“记数字”游戏的例子。

大致玩法是:显示一个个位数组成的随机数序列,一秒之后删除这个数字序列,然后由玩家输入序列中的数字,输对了就继续玩,如果连续三次输入正确就在序列中增加一个数;错了就给出分数,然后询问是否重新开始游戏。

我这也不完全算照抄,就是看懂了书上讲的方法,模仿着写一遍,写到中途就卡住了,问题出在“一秒之后删除这个数字序列”这一步。代码如下:

程序代码:
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <stdbool.h>

int main(void)
{
    /* declare variables and initialize */
    char another_game = 'Y';
    
    /* variables for random numbers */
    time_t seed = 0;
    int number = 0;
    int sequence_length = 0;
    
    /* variables for 1 sec delay before removing the sequence */
    time_t now = 0;
    
    
    /* other variables */
    int counter = 0;
    bool correct = true;
    
    
    /* description of the game */
    printf("\nTo play a Simple Simon,");
    printf("watch the screen for a sequence of digits.");
    printf("\nWatch carefully, as the digits are only displayed for a second!");
    printf("\nThe computer will remove them , and then prompt you to enter the same sequence.");
    printf("\nWhen you do, you must put spaces between the digits. \n");
    printf("\nGood Luck!\nPress Enter to play\n");
    scanf("%c",&another_game);
    
    /* code of the game */
    do {
        /* initialize the game */
        sequence_length = 2;
        counter = 0;
        
        
        while (correct) {
            /* initializing now */
            now = clock();
            
            /* increasing sequence length by every 3 correct guess */
            //printf("counter at beginning: %d\n",counter);
            sequence_length += counter++%3 == 0;
            //printf("counter changed to: %d\n",counter);
            
            /* generating random numbers */
            seed = time(NULL);
            srand((unsigned)seed);
            for (int i = 1; i <= sequence_length; i++) {
                printf("%d ",rand()%10);
            }
            /* remove the numbers in one second */
            for (; clock() - now < CLOCKS_PER_SEC * 2; ) ; //这里是关于1秒延迟的问题
            printf("\r"); //这里是关于 \r 的问题
            for (int k = 1; k <= sequence_length; k++) {
                printf("  ");
            }
            
            /* user input and check */
            srand((unsigned)seed);
            for (int j = 1; j <= sequence_length; j++) {
                scanf("%d",&number);
                if (number != rand()%10) {
                    correct = false;
                    break;
                }
                
                
            }
            printf("%s",correct ? "Correct!\n\n" : "Wrong!\n\n");
        }
        
        
        /* out put score */
        
        
        /* check if another game is required */
        printf("Do you want to play another game(Y/N)?\n\n");
        scanf("%c",&another_game);
    }while (toupper(another_game) == 'Y');
    
    return 0;
}


问题1: 延迟
先说1秒延迟的问题,延迟到是延了,可是延的不是地儿。应该是随机数字序列显示之后,延迟1秒,在删序列;可是我的运行结果是延迟1秒后才显示数字序列。从代码的顺序上来说不应该是这么个结果,求教各位前辈这是为啥,怎么解决。

问题2: \r
然后关于 \r ,书上讲的删除序列的方法是:让光标回到数字序列这一行的开头,然后打N个空格,把序列盖过去(这方法八成是为了迁就初学者知识量有限。。。)
但我打出 \r 之后没有回到这一行的开头,而是和 \n 的效果一样,跑下一行去了。

我在网上查到了问题的原因(来自一个叫“星空”的百度空间),但仍然不知道怎么解决:
C语言\r\n和\n区别\r是回车符,\n是换行符计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。 这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。 后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<回车><换行>”,即“ \r\n”;Mac系统里,每行结尾是“<回车>”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

我做练习的环境是MAC上的Xcode,所以 \r 是回车+换行效果。
请教各位前辈,我这个地方应该怎么处理?还有,比较好奇,在MAC上能实现 \r 在windows中单纯回车的效果吗?怎么弄?

先拜谢所有读帖者。
搜索更多相关主题的帖子: 开始游戏 经典 color C语言 
2014-06-06 17:53
砖家的谎言
Rank: 12Rank: 12Rank: 12
等 级:禁止访问
威 望:30
帖 子:693
专家分:3898
注 册:2013-12-6
收藏
得分:10 
"可是我的运行结果是延迟1秒后才显示数字序列。"显示数据,说明你延迟的位置放置问题

我不是砖家,要努力成为砖家。
2014-06-06 18:03
zig219
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2014-5-29
收藏
得分:0 
这个while循环里的东西应该是从上往下执行的吧?那个打印数字序列的for循环明明写在这个控制1秒延迟的循环上边啊。求解。

程序代码:
            /* generating random numbers */
            seed = time(NULL);
            srand((unsigned)seed);
            for (int i = 1; i <= sequence_length; i++) {
                printf("%d ",rand()%10);
            }
            /* remove the numbers in one second */
            for (; clock() - now < CLOCKS_PER_SEC * 2; ) ; //这里是关于1秒延迟的问题
            printf("\r"); //这里是关于 \r 的问题
            for (int k = 1; k <= sequence_length; k++) {
                printf("  ");
            }
2014-06-06 18:08
zig219
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2014-5-29
收藏
得分:0 
我刚刚这样试了一下:

程序代码:
            for (; clock() - now < CLOCKS_PER_SEC; ){
                printf("%lu\n\n",clock() - now);
            }


这个延迟循环确实是在输出数字序列之后执行的, 数字序列和下边的一行空格之间输出了一堆tick值。

但是又这样试了一下:
程序代码:
            /* generating random numbers */
            seed = time(NULL);
            srand((unsigned)seed);
            for (int i = 1; i <= sequence_length; i++) {
                printf("%d ",rand()%10);
            }
            /* remove the numbers in one second */
            for (; clock() - now < CLOCKS_PER_SEC; );
            printf("\ntest delay");


目测结果是延迟了1秒以后,数字序列和"\ntest delay"是同时出现的。
2014-06-06 18:51
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:10 
你的代码没细看,先答第二个问题,用putchar(13)输出试试,不要用任何转义字符。我没用过Mac,不清楚它如何处理'\r',但原理上直接输出ascii字符不会转义。

[ 本帖最后由 TonyDeng 于 2014-6-6 20:55 编辑 ]

授人以渔,不授人以鱼。
2014-06-06 20:52
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
关于第一个问题,试试把延时数增大点看看什么现象,比如10秒。大概估计跟操作系统有关,需要观察现象验证猜想。

授人以渔,不授人以鱼。
2014-06-06 20:58
z18676166721
Rank: 1
等 级:新手上路
帖 子:16
专家分:9
注 册:2011-11-4
收藏
得分:0 
今天想使用printf()函数在串口上每秒输出一个‘C’字符,实现在串口上如CCCCCC的显示,但直接使用printf("C");语句时,要么不输出,要么一下子输出很多CCCCC。

而使用printf("C\n");语句时则可正常输出显示,但这不是我要的输出格式。

 

事实上这个问题涉及到printf()输出缓冲的问题。

对于标准输出设备stdout,输出一般都有缓冲,当遇到刷新标志或缓冲满时才把缓冲的数据输出到标准输出设备中。

对于printf()函数,其使用的输出设备就是标准输出设备stdout,且采用行缓冲式的输出,当printf()遇到\n时,或者缓冲区满时,才会将缓冲区里的内容刷新到标准输出(stdout).

因此, printf("C"); 等语句的显示不能立刻显示在串口上,而printf("C\n");则可以立刻输出到串口中。

为了解决这个问题,可以通过:fflush(stdout);解决,即:

[cpp] view plaincopy
printf("C");  
  
fflush(stdout);  
从而实现要求的CCCCCCCC输出格式。

注:在C语言库函数中,是有fflush()这个库函数的。

new gate ,新的一扇门
2015-05-07 18:22
z18676166721
Rank: 1
等 级:新手上路
帖 子:16
专家分:9
注 册:2011-11-4
收藏
得分:0 
原帖地址
谢谢,根据你的提示,两个问题都解决了.
http://blog.
http://ydiandiandian.

new gate ,新的一扇门
2015-05-07 18:23
快速回复:[新手请教]照抄书上的例子,运行结果和书上写的不一样(延迟方法和\ ...
数据加载中...
 
   



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

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