嵌入式 C语言实现进度条以及实现带进度条的CP命令等编程示例收集一

2019-07-12 18:32发布

Linux用C语言实现进度条

#include
#include
#include
#include
void drawper(int iFirst, int iSecnd, char* spOut)
{
  static int iCrlmm = 0;
  int iPer = iFirst*100/iSecnd;

  if(iFirst==iSecnd)
    sprintf(spOut, "[ %d%] ",  iPer);
  else if( iCrlmm == 0)
    sprintf(spOut, "[| %d%] ",  iPer);
  else if( iCrlmm == 1)
    sprintf(spOut, "[/ %d%] ",  iPer);
  else if( iCrlmm == 2)
    sprintf(spOut, "[- %d%] ",  iPer);
  else if( iCrlmm == 3)
    sprintf(spOut, "[\ %d%] ", iPer);

  if(iCrlmm==3)
    iCrlmm=0;
  else
    iCrlmm++;
}
void proessview()
{
  char szStr[255] = "=====================================================================";
  int  iStrLen = strlen(szStr);
  char cTmp       = '>';
  char szOut[10]  = "";
  int i = 0;
  for( i= 0; i<=iStrLen; i++)
  {
    memset( szOut, 0, sizeof(szOut) );
     
    szStr[i] = cTmp;
    drawper(i, iStrLen, szOut);
    memcpy(szStr+iStrLen, szOut, strlen(szOut) );
    fseek(stdout, 0, SEEK_SET);
    fprintf(stdout, szStr);
    fflush(stdout);
  
    usleep(300000);
  }
}
int main()
{
   proessview();
   return 1;
}
  我在Linux字符终端上实现了两种有趣的彩 {MOD}进度条。
一种是采取渐进打印的动画效果,另一种是循环打印。
用C语言和shell脚本实现了这两种方式,我不怎么
擅长shell脚本,所以代码写得比较凌乱。两个程序
没事儿的时候可以拿来解闷。
具体的实现方式可以看后面的代码。

测试环境:
OS:    fedora 11
gcc:   Red Hat 4.4.0-4
shell: bash 4.0.16

C语言程序编译:
    gcc -std=gnu99 -g -W -Wall -Wextra -o mytest main.c

执行:
渐进效果:
    ./mytest
    ./mytest.sh
随便加个选项,就变成循环效果:
    ./mytest a
    ./mytest.sh a


main.c:
================================================================
// 2011年 11月 15日 星期二 11:44:52 CST
// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
// K.I.S.S
// S.P.O.T

#include
#include

#include


#define  BAKBLK  "e[40m"   // Black - Background
#define  BAKRED  "e[41m"   // Red
#define  BAKGRN  "e[42m"   // Green
#define  BAKYLW  "e[43m"   // Yellow
#define  BAKBLU  "e[44m"   // Blue
#define  BAKPUR  "e[45m"   // Purple
#define  BAKCYN  "e[46m"   // Cyan
#define  BAKWHT  "e[47m"   // White

#define  CLRRST   "e[0m"

#define COLOR_NUM 8
#define DELAY_TIME 500000


static const char *color_blocks[] = {
    BAKRED"   "CLRRST,
    BAKGRN"   "CLRRST,
    BAKYLW"   "CLRRST,
    BAKBLK"   "CLRRST,
    BAKBLU"   "CLRRST,
    BAKPUR"   "CLRRST,
    BAKCYN"   "CLRRST,
    BAKWHT"   "CLRRST
};


static void reset_line();
static unsigned int circle_print_line(unsigned int);
static unsigned int sque_print_line(unsigned int);



int main(int argc, char *argv[])
{
    unsigned int b = 0;
    unsigned int (*print_progress)(unsigned int);

    if(argc != 1)
        print_progress = circle_print_line;
    else
        print_progress = sque_print_line;

    for(;;) {
        reset_line();
        b = print_progress(b);
        usleep(DELAY_TIME);
    }
    return 0;
}

static void reset_line()
{
    printf("                         ");
}

static unsigned int circle_print_line(unsigned int b)
{
    assert(b < COLOR_NUM);
    //printf(" ");
    unsigned int i = b;

    do {
        printf(color_blocks[i]);
        fflush(stdout);
        i = (i + 1) % COLOR_NUM;
    } while(i != b);

    return (b - 1) % COLOR_NUM;
}

static unsigned int sque_print_line(unsigned int c)
{
    assert(c < COLOR_NUM);

for(unsigned int i = COLOR_NUM - c - 1; i < COLOR_NUM; ++i) {
        printf(color_blocks[i]);
        fflush(stdout);
    }
    return (c + 1) % COLOR_NUM;
}

=====================================================================


mytest.sh:
=====================================================================
#!/bin/bash -


# 2011年 11月 15日 星期二 12:17:21 CST
# author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
# K.I.S.S
# S.P.O.T


#set -x

BAKBLK="echo -en \e[40m \e[0m"
BAKRED="echo -en \e[41m \e[0m"
BAKGRN="echo -en \e[42m \e[0m"
BAKYLW="echo -en \e[43m \e[0m"
BAKBLU="echo -en \e[44m \e[0m"
BAKPUR="echo -en \e[45m \e[0m"
BAKCYN="echo -en \e[46m \e[0m"
BAKWHT="echo -en \e[47m \e[0m"

COLOR_NUM=8
DELAY_TIME=0.5

reset_line()
{
    echo -en "\r                         \r"
}

sque_print_blocks()
{
    j=0
    $BAKGRN
    $BAKGRN
    $BAKGRN
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKRED
    $BAKRED
    $BAKRED
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKBLK
    $BAKBLK
    $BAKBLK
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKYLW
    $BAKYLW
    $BAKYLW
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKBLU
    $BAKBLU
    $BAKBLU
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKPUR
    $BAKPUR
    $BAKPUR
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKCYN
    $BAKCYN
    $BAKCYN
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
    $BAKWHT
    $BAKWHT
    $BAKWHT
    j=$((j+1))
    if [ $j -gt $1 ]
    then
        sleep $DELAY_TIME
        return
    fi
}

circle_print_blocks()
{
    i="$1"
    j=0
    while [ true ]
    do
        if [ "$i" -le "0" ]
        then
            $BAKGRN
            $BAKGRN
            $BAKGRN
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "1" ]
        then
            $BAKRED
            $BAKRED
            $BAKRED
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "2" ]
        then
            $BAKBLK
            $BAKBLK
            $BAKBLK
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "3" ]
        then
            $BAKYLW
            $BAKYLW
            $BAKYLW
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "4" ]
        then
            $BAKBLU
            $BAKBLU
            $BAKBLU
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "5" ]
        then
            $BAKPUR
            $BAKPUR
            $BAKPUR
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "6" ]
        then
            $BAKCYN
            $BAKCYN
            $BAKCYN
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi

        if [ "$i" -le "7" ]
        then
            $BAKWHT
            $BAKWHT
            $BAKWHT
            j=$((j+1))
            i=$(((i+1) % COLOR_NUM))
        fi
        if [ $j -gt "7" ]
        then
            sleep $DELAY_TIME
            return
        fi
    done
}


i=0
while [ true ]
do
    if [ -z "$1" ]
    then
        sque_print_blocks $i
    else
        circle_print_blocks $i
    fi
    i=$(((i+1) % COLOR_NUM))
    reset_line
done
很想实现在linux控制台上打印进度条,这样对于运行时间长的程序就不至于让用户等的不耐烦了。 众所周知,ncurse库能很方便的在控制台上输出一些很花样信息,当然包括进度条这样小case的东西啦。但是,唯一然人不能接受的是,为了让控制台上及时的显示输出字符,必须用flush之类的函数刷新缓冲区,这样就导致要清除当前屏幕。如果,屏幕上有一些信息很重要的话,清除屏幕是非常让你难以理解的。另外termcap库也能实现这些功能,但是tgoto,tputs这样的函数直到现在我也不会用。 天无绝人之路,根据rpm的进度条显示代码,我编写了以下的程序,可以方便的实现进度条的打印。当然你也可以随便在自己的程序中加上这些代码(只要你愿意哈)。 #include
#include
#include

#define LEN 40
#define TIM 50000000
#define done '+'
#define none '-'
#define del() putchar('')
#define motion()
{
 
 
putchar(done);fflush(stdout);delay
();
  del();

 
putchar('x');fflush(stdout);delay
();
  del();

 
putchar('|'); fflush(stdout);delay
();
  del();

 
putchar('/'); fflush(stdout);delay
();
  del();

 
putchar(done);

}


intmode =-1
;

voiddelay
()
{
  inti
;
  for(i=0;i<TIM;i++)
;
}

voidloop(inti, intj)
{
 
//print progress bar.
  for(j=0;j<i-1;j++)

   
putchar(done
);
  motion
();
 
//print space after progress bar.
  for(j=1;j<LEN-i;j
++)
    putchar(none
);
}

voiddomino(inti, intj
)
{
  for(j=0;j<i-1;j
++)
    putchar('_'
);
  putchar('/');fflush(stdout
);
  delay();del
();
  putchar('_');fflush(stdout
);
  delay
();
  for(j=1;j<LEN-i;j
++)
    putchar('|'
);
}

voidsharp(inti, intj
)
{
  for(j=0;j<i;j
++)
    putchar('#'
);
  for(j=1;j<LEN-i;j
++)
    putchar(' '
);
}

voidadd(inti, intj
)
{
  for(j=0;j<i;j
++)
    putchar('+'
);
  for(j=1;j<LEN-i;j
++)
    putchar('-'
);
}

voidprogress
()
{
  inti,j,k
;
  for(i=1;i<LEN;i++)
{
    if(i != 1)
{
     
//delete all character of current line.
      for(k=0;k<LEN+6;k
++)
        putchar(''
);
   
}
    switch(mode)
{
    case0
:
      loop(i,j);break
;
    case1
:
      domino(i,j);break
;
    case2:

     
sharp(i,j);break
;
    case3
:
    default
:
      add(i,j);break
;
   
}

   
//finally, print percent.
    fprintf(stdout,"  %3d%%",i*100/(LEN-1
));
    fflush(stdout);
//output message on time, please.
   
//delay();
    sleep(1
);
 
}
}

intmain(intargc,char*argv
[])
{
  intc
;

  if(argc< 2
)
    return1
;

  while((c=getopt(argc,argv,"ldsa"))!= EOF)
{
    switch(c)
{
    case'l'
:
      mode= 0;break
;
    case'd'
:
      mode= 1;break
;
    case's'
:
      mode= 2;break
;
    case'a'
:
      mode= 3;break
;
    default
:
      return1
;
   
}
 
}
  progress
();
  return0
;
}