A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 无尽可能 中级黑马   /  2014-7-6 09:59  /  2684 人查看  /  18 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 无尽可能 于 2014-7-6 11:34 编辑

输入一组数进行排序(个数不固定)
例如:
输入 :         1 3 6 9 85 1
输出结果为:1 1 3 6 9 85
提示1:(排序不是重点)重点是如何判断接收结束。提示2:不要眼高手低,写出代码,你跑下程序就知道会有意想不到的bug


18 个回复

倒序浏览
这题真难。。想一上午试了N多办法。。都失败了。。。
回复 使用道具 举报
fantacyleo 来自手机 金牌黑马 2014-7-6 12:21:48
藤椅
搞清楚scanf的工作方式,没有任何难度。输入结束后加一个EOF标记就行了。win下是ctrl+z,mac下是ctrl+d
回复 使用道具 举报
本帖最后由 fantacyleo 于 2014-7-6 12:51 编辑

这题不是编程的问题。我想大多数人都会写出类似这样的代码:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.         int a[10];
  5.         int b, i=0;
  6.         while(scanf("%d", &b) != -1)
  7.            a[i++]=b;

  8.         int len = i;

  9.         for(i = 0; i < len; i++)
  10.                 printf("%d\n", a[i]);
  11. }
复制代码

代码没问题。问题仅仅在于输入结束时要加上结束标记,mac下可以连续输入两次ctrl+d,或者换行后输入一次ctrl+d,向scanf发出end-of-file信号,停止读取
回复 使用道具 举报
楼上正解…………~~
回复 使用道具 举报
写了一段,不知道符合需求不,大家看看

#include <stdio.h>

int main()
{
    int val[100] = {0};
    int i = -1, k, j;
    int min;
    printf("请输入数字\n,当输入-999输入停止.\n");
    //输入要排序的数字序列
    while(1)
    {
        i++;
        scanf("%d",&val[i]);
        if(val[i]==-999)
        {
            break;
        }
    }
    //排序
    for (k=0; k<i; k++)
    {
        for (j=k;j<i-1; j++)
        {
            if(val[k]>val[j+1])
            {
                min = val[j+1];
                val[j+1] = val[k];
                val[k] = min;
            }
        }
    }
    //输出排序之后的数字序列
    for (k=0; k<i; k++)
    {
        printf("%d  ",val[k]);
    }
   
    return 0;
}
回复 使用道具 举报
本帖最后由 幕夏 于 2014-7-6 18:57 编辑

终于写出来了 ,确实不容易,我这可以正确运行,你们运行试试,看看有什么问题么,注意按空格分隔每组数字,最后按Enter结束,实现了让Enter作为结束输入循环的功能。
  1. #include <stdio.h>

  2. int atoii(char *s) // 这是一个让输入的数字字符串转换为整形的函数。
  3. {
  4.    
  5.     int num = 0;
  6.    
  7.     while(*s>='0' && *s<='9')
  8.     {
  9.         num *= 10;  
  10.         num +=*s-'0'; // *s-'0' 这个可以得到当前输入的数字字以整形形式存放
  11.         s++;    //循环到第二个输入的字符
  12.     }
  13.     return num;
  14. }


  15. int main(int argc, char *argv[])
  16. {
  17.         int a[100];     // 存放转换后的整数,规定了输入上限为100.
  18.         char s[100];  //  存放输入的字符串(数字也当做字符串输入,这样为了后面得到enter的字符'\n'以便于停止输入循环)。
  19.         int temp;
  20.         int i=0;
  21.         int decide=0;// 设置decide这个变量,是为了帮助判断什么时候结束循环,下面我设置了decide=1的时候结束循环。
  22.         while (i<100)
  23.         {   
  24.                
  25.                 for(int h=0;h<100;h++){
  26.                         scanf("%c",&s[h]);

  27.                         if(s[h]=='\n'){// 若输入enter,认为这一组数已经输入完毕,让decide为1,以便于让最外层的循环结束,然后接着结束这个循环。
  28.                                 s[h]='\0';//补上'\0'作为字符串结束的标志。
  29.                                 decide=1;
  30.                                 break;        
  31.                         }else if(s[h]==' '){// 若输入空格,认为一个数已经输入完毕,结束这个循环,将值传个函数atoii()转换为整数。
  32.                                                 s[h]='\0';
  33.                                                 break;
  34.                                         }        
  35.                         
  36.                 }

  37.                 a[i]=atoii(s);// 函数调用
  38.   
  39.                 for (int j=i;j>0 ;j-- ) // 这是个比较排序的循环,
  40.                 {
  41.                         if (a[j]<a[j-1])
  42.                         {
  43.                                 temp=a[j];a[j]=a[j-1];a[j-1]=temp;
  44.                         }

  45.                 }

  46.                 i++;
  47.                  if(decide==1) break;//因为 输入 了enter键所以结束 while()循环
  48.                
  49.         }
  50.         // 用上面步骤赋给的i值做判断输入结尾,输出整形数组a。
  51.         for (int k=0;k<i ;k++ )
  52.         {
  53.                 printf("%d ",a[k]);
  54.         }
  55.         
  56.         
  57.         return 0;
  58. }
复制代码

回复 使用道具 举报
fantacyleo 发表于 2014-7-6 12:46
这题不是编程的问题。我想大多数人都会写出类似这样的代码:

代码没问题。问题仅仅在于输入结束时要加上结 ...

搞懂了。
回复 使用道具 举报
!!好庞大的工程,竟然恐怖如斯
回复 使用道具 举报
原来是这样……
回复 使用道具 举报
fantacyleo 发表于 2014-7-6 12:21
搞清楚scanf的工作方式,没有任何难度。输入结束后加一个EOF标记就行了。win下是ctrl+z,mac下是ctrl+d ...

提示,定义整型数组,只能以回车结束。
回复 使用道具 举报
无尽可能 发表于 2014-7-8 23:45
提示,定义整型数组,只能以回车结束。

是整型数组啊。回车结束也没问题,fgets读入整行嘛,然后遍历字符串,按空格识别、转换数字、存入数组。我倒是很好奇你说的bug是指什么?
回复 使用道具 举报
fantacyleo 发表于 2014-7-8 23:58
是整型数组啊。回车结束也没问题,fgets读入整行嘛,然后遍历字符串,按空格识别、转换数字、存入数组。 ...

问题已经解决了,实际上不需要转换,
用scanf接收整数直接存入数组,getchar判断是否'\n',这样就可以判断结束了。
回复 使用道具 举报
无尽可能 发表于 2014-7-9 00:16
问题已经解决了,实际上不需要转换,
用scanf接收整数直接存入数组,getchar判断是否'\n',这样就可以判 ...

嗯,对。这个方法更好
回复 使用道具 举报
请教,能否给出代码,我自己试着用getchar()实在不知怎么将代码敲出。
回复 使用道具 举报
幕夏 发表于 2014-7-9 01:25
请教,能否给出代码,我自己试着用getchar()实在不知怎么将代码敲出。
  1. #include <stdio.h>
  2. int main()
  3. {
  4.         int a[10];
  5.         int b, i=0;
  6.         while(scanf("%d", &b) != -1)
  7.         {
  8.              a[i++]=b;
  9.              if(getchar() == '\n')
  10.                  break;
  11.          }

  12.         int len = i;

  13.         for(i = 0; i < len; i++)
  14.                 printf("%d\n", a[i]);
  15. }
复制代码
回复 使用道具 举报

哦,这样啊,我就是不明白为什么getchar接收过用户输入后,还能再传给scanf函数。
回复 使用道具 举报
幕夏 发表于 2014-7-9 01:55
哦,这样啊,我就是不明白为什么getchar接收过用户输入后,还能再传给scanf函数。 ...

没传啊。getchar和scanf都是在一个缓冲区中读取数据的。lz的输入格式中每个数之间有一个空格,getchar正好吃掉了这个空格,而不会把下一次本该scanf读取的整数的一部分给吃掉
回复 使用道具 举报
fantacyleo 发表于 2014-7-9 01:58
没传啊。getchar和scanf都是在一个缓冲区中读取数据的。lz的输入格式中每个数之间有一个空格,getchar正 ...

恩恩,明白了,谢谢了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马