my blog my blog

Category: C Program
ASCII码介绍及ASCII码表

 

直接CP来自百科的介绍:

缩写:ASCII
英文全称:American Standard Code for Information Interchange
 
美国信息交换标准代码是一种用于信息交换的美国标准代码。7位字符集广泛用于代表标准美国键盘上的字符或符号。通过将这些字符使用的值标准化,ASCII允许计算机和计算机程序交换信息。ASCII字符集是与ANSI字符集中的前面128个(0-127)字符相同。
美国信息交换标准代码ASCII为"美国信息交换标准代码"十个字对应英文的缩写,ASCII文件是简单的无格式文本文件,可以由任何计算机所识别,Windows中的记事本及任何文字处理程序都可以阅读及创建ASCII文件。
在计算机中,所有的数据在存储和 运算时都要使用二进制数表示,同样的,象a、b、c、d这样的52个字母(包括大写)、以及0、1、2等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪个数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通讯而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了所谓的ASCII编码,统一规定了上述常用符号用哪个二进制数来表示。
 
八进制十六进制十进制字符八进制十六进制十进制字符
000nul1004064@
111soh1014165A
222stx1024266B
333etx1034367C
444eot1044468D
555enq1054569E
666ack1064670F
777bel1074771G
1088bs1104872H
1199ht1114973I
120a10nl1124a74J
130b11vt1134b75K
140c12ff1144c76L
150d13er1154d77M
160e14so1164e78N
170f15si1174f79O
201016dle1205080P
211117dc11215181Q
221218dc21225282R
231319dc31235383S
241420dc41245484T
251521nak1255585U
261622syn1265686V
271723etb1275787W
301824can1305888X
311925em1315989Y
321a26sub1325a90Z
331b27esc1335b91[
341c28fs1345c92\
351d29gs1355d93]
361e30re1365e94^
371f31us1375f95_
402032sp1406096
412133!1416197a
422234"1426298b
432335#1436399c
442436$14464100d
452537%14565101e
462638&14666102f
472739`14767103g
502840(15068104h
512941)15169105i
522a42*1526a106j
532b43+1536b107k
542c44,1546c108l
552d451556d109m
562e46.1566e110n
572f47/1576f111o
603048016070112p
613149116171113q
623250216272114r
633351316373115s
643452416474116t
653553516575117u
663654616676118v
673755716777119w
703856817078120x
713957917179121y
723a58:1727a122z
733b59;1737b123{
743c60<1747c124|
753d61=1757d125}
763e62>1767e126~
773f63?1777f127del

 

 

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH3365A97a
2STX3466B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR4577M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383X115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92\124|
29GS61=93]125}
30RS62>94^126~
31US63?95127DEL

 

 

NULVT 垂直制表SYN 空转同步
SOH  标题开始FF   走纸控制ETB   信息组传送结束
STX  正文开始CR   回车CAN   作废
ETX  正文结束SO   移位输出EM   纸尽
EOY  传输结束SI   移位输入SUB   换置
ENQ  询问字符DLE   空格ESC   换码
ACK  承认DC1   设备控制1FS   文字分隔符
BEL  报警DC2   设备控制2GS   组分隔符
BS  退一格DC3   设备控制3RS   记录分隔符
HT  横向列表DC4   设备控制4US   单元分隔符
LF  换行NAK   否定DEL   删除
关于64位linux系统无法执行32位程序的解决方法

 

前阵子就是因为32位lib的关系没有正常执行永中office安装,当然,我的问题不是缺少32位库,而是64位的库也有问题,呃,这个今天不讨论了,今天就说说最基本的解决方案。

当你执行一个32位程序的时候,你可能会发现提示No such file or directory,这就是说明你的64位系统没有安装32位的lib库,如何知道一个程序是32位还是64位呢,也很简单,可以通过readelf来看。呃,如果你确定你执行的是32位程序,而你是64位系统,则出现No such file or directory错误就是因为你缺少了32位的库文件。解决方法也很简单:

对于Arch Linux用户:

添加下面几行到 /etc/pacman.conf 启用该软件仓库:

  1. [multilib] 
  2. Include = /etc/pacman.d/mirrorlist 

然后执行:

  1. sudo pacman -Syy 
  2. sudo pacman -S lib32-glibc 

对于Ubuntu用户:

  1. sudo apt-get install ia32-libs 

对于fedora用户:

  1. sudo yum install glibc.i686 

一般的程序就可以运行了,当然也可能还需要一些其它的32位库,可根据实际情况来解决。

linux系统编程pdf教程下载

 

今天为大家推荐一本linux系统编程的书.

书名:linux system programming(linux系统编程)
作者: Robert Love
出版社: O’Reilly

翻译是国内哈工大的同学做的,翻译还是很不错的.

linux系统编程目录:


前言
第一章 介绍与基本概念
第二章 文件I/O
第三章 缓冲式I/O
第四章 高级文件I/O
第五章 进程管理
第六章 高级进程管理
第七章 文件和目录管理
第八章 内存管理
第九章 信号
第十章 时间
附录GCC对C语言的扩展

奶牛也是通过这个学期我们开的linux课程开始接触linux的系统编程,发现其实用心学习也没有那么难~~~加油鸟,要有各种忙碌鸟~~~

下载地址:点此下载linux系统编程pdf中文版

linux c编程open() read() write()函数的使用方法及实例

 

今天把文件IO操作的一些东东整理下.基本的,对于锁机制下次再整理.常用的文件IO函数有标题的三个open() read() write() .首先打开一个文件使用open()函数,然后可以获取到一个文件描述符,这个就是程序中调用这个打开文件的一个链接,当函数要求到文件描述符fd的时候就把这个返回值给函数即可.read跟write都差不多,格式:read(文件描述符,参数,权限) write(文件描述符,参数,权限),返回值是读取或写入的字符数.其中的权限可以省略,文件描述符就是open()函数的返回值,而参数呢有O_RDONLY(只读) O_WRONLY(只写) O_RDWR(读写) O_CREAT(若不存在则新建) O_TRUNC(若不为空则清空文件)等.对函数想有更多了解可以察看linux下c编程的函数手册.

有些程序还是得自己动手写一下,自己不写就很难知道问题错在哪里,不知道自己是不是真的可以写出来.

写个小例子:文件备份程序

功能:输入一个"文件名",将生成"文件名.backup"的备份文件.若输入量超过两个或者无输入量,报错,若文件不存在或无权限,报错.成功返回提示.

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <string.h> 
  4. #include <fcntl.h> 
  5.  
  6. int main(int argc,char *args[]) { 
  7.     char buff[1024]; 
  8.     int fd1,fd2,i; 
  9.     int baksize = sizeof(args[1])+7; 
  10.     char bakfile[baksize]; 
  11. // input one file only 
  12.     if(argc != 2){ 
  13.         printf("Input one file a time!\n"); 
  14.         exit(1); 
  15.     } 
  16. //bakfile="XXX.backup"设置备份文件名称 
  17.     strcpy(bakfile,args[1]); 
  18.     strcat(bakfile,".backup"); 
  19. //open() 
  20.     fd1 = open(args[1],O_RDONLY,0644); 
  21.     fd2 = open(bakfile,O_RDWR|O_CREAT|O_TRUNC); 
  22.     if((fd1 < 0)||(fd2 < 0)){ 
  23.         printf("Open Error!Check if the file is exist and you have the permission!\n"); 
  24.         exit(1); 
  25.     }  
  26. //read from fd1 and write buff to fd2 
  27.     while((i = read(fd1,buff,sizeof(buff))) > 0) { 
  28.     write(fd2,buff,i);//这里需要用读取到的字符数,否则会出错,因为buff数组有可能未被全覆盖 
  29.     } 
  30.     close(fd1); 
  31.     close(fd2); 
  32.     printf("Backup done!\n"); 
  33.     exit(0); 
  34.      

 

linux c编程main函数的参数以及带参实例

 

写c程序,让用户一次又一次的输入参数输入回车是很不友好也很不明智的方法.所以为了更好的用户体验,参数应该可以在执行程序的时候直接就可以把参数都设定完成.好吧,说下main函数的参数.

一般我们就给main两个参数,写成如下形式:

main (int argc,char *argv[])

其中argc是统计的参数个数,默认为1.因为执行文件的文件名就是一个参数.

理所当然,argv[0]也是默认就有的,内容就是文件名.

当然,这个argc跟argv是可以更换为其它名称的,只要数据类型对就ok的.

解释这些估计就了解了个差不多了.然后直接看个实例就应该可以理解了.

实例:调用wget来下载一个文件.要求可以直接输入下载地址,如果输入两个参数则报错,提示使用方法:

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4.  
  5. int main (int argc,char *args[]){ 
  6.     if(argc > 2){ 
  7.     printf("Error input!\nUsages:wget [http/ftp url]\n"); 
  8.     exit(1); 
  9.     } 
  10.     char *url = args[1]; 
  11.     printf("The URL is:%s\n",url); 
  12.     execlp("wget","wget","-c",url,NULL); 
  13.     exit(0); 

 

linux下daemon守护进程的编写实例

 

对于daemon守护进程,可能大多数朋友了解不多.对于守护进程,也就是说它由init直接来管理.举个例子:当我们打开一个terminal,输入gedit,然后编辑一些字,不要关闭gedit,这时候回到终端terminal,按ctrl+c,这时候你看到了什么,gedit关闭了对不对.因为gedit可以看成是一个进程哇,而且这时候终端并没有显示$或者#,结束的肯定是gedit的进程哇.如果我们想让这些进程在我们的后台运行,不受到terminal的限制,就需要来写一个daemon守护进程了.

这里说一下具体的方法:

1.fork()一个子进程

2.把父进程exit(0)退出,这时候子进程成为了一个孤立的进程,由init接管

3.setsid(),脱离控制终端,登录会话和进程组

介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号 (PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。 控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使 进程成为会话组长.当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。

4.close(i) ,关闭文件描述符

进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。

5.umask(0);重置文件权限掩码

6.更改当前的工作目录chdir(),这个可选

ok,这样子一个daemon就差不多了.

下面写了一个编程的实例,用wget 后台执行一个下载,然后把下载信息记录到info.txt文件中以便察看下载结果.

 

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <string.h> 
  4. #include <fcntl.h> 
  5. #include <sys/types.h> 
  6. #include <sys/wait.h> 
  7. #include <unistd.h> 
  8.  
  9. int main(){ 
  10.     pid_t daemon; 
  11.     int i,fd; 
  12.      
  13.     daemon = fork(); 
  14.     if(daemon < 0){ 
  15.         printf("Fork Error!"); 
  16.         exit(1); 
  17.     } 
  18.     else if (daemon > 0 ) { 
  19.         printf("Father process exited!"); 
  20.         exit(0); 
  21.     } 
  22.     setsid(); 
  23.     umask(0); 
  24.     for (i = 0;i < getdtablesize();i++){ 
  25.         close(i); 
  26.     } 
  27.     system("wget -c http://cdimage.ubuntu.com/daily-live/current/quantal-desktop-amd64.iso >info.txt 2>&1"); 
  28.     exit(0); 
  29.  

 

linux c编程信号处理的一些实例signal sigaction

 

 刚接触linux下的c编程,记录一下吧.对于信号,就是我们经常用的那个kill,kill可以发送很多信号,当然,我们也可以通过程序来实现,我们甚至可以来定义对于不同的信号的处理,比如ctrl+c可能并不能退出我们的程序,因为我们可以监视ctrl+c发送的SIGINT信号,并且用我们自己的功能来进行处理.PS:发现写代码也是个需要手感的事儿,意识到该多看看vim的配置鸟~~~自动不全一定要强大才行哇~~~

先把课本上的两个小实例放上来,记录下:

1.signal()的使用

捕捉ctrl+c发送的SIGINT与ctrl+\发送的SIGQUIT信号

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <signal.h> 
  4.  
  5. void my_func(int sign_no) { 
  6.     if (sign_no == SIGINT) { 
  7.         printf("I have get SIGINT\n"); 
  8.     } else if (sign_no == SIGQUIT) { 
  9.         printf("I have get SIGQUIT\n"); 
  10.     } 
  11.  
  12. int main() { 
  13.     printf("waiting for signal SIGINT or SIGQUIT ... \n"); 
  14.     signal(SIGINT, my_func); 
  15.     signal(SIGQUIT, my_func); 
  16.     pause(); 
  17.     exit(0); 

2.sigaction()的使用<—感觉是signal的一个变种

同样是捕捉ctrl+c发送的SIGINT与ctrl+\发送的SIGQUIT信号

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <signal.h> 
  4.  
  5. void my_func(int sign_no) { 
  6.     if (sign_no == SIGINT) { 
  7.         printf("I have get SIGINT\n"); 
  8.     } else if (sign_no == SIGQUIT) { 
  9.         printf("I have get SIGQUIT\n"); 
  10.     } 
  11.  
  12. int main() { 
  13.     struct sigaction action; 
  14.     printf("waiting for signal SIGINT or SIGQUIT ... \n"); 
  15.     action.sa_handler = my_func; 
  16.     sigemptyset(&action.sa_mask); 
  17.     action.sa_flags = 0; 
  18.     sigaction(SIGINT, &action, 0); 
  19.     sigaction(SIGQUIT, &action, 0); 
  20.     pause(); 
  21.     exit(0); 

3.信号集

默认对信号进行状态阻塞,此时输入任何信号都不执行,ctrl+c 与ctrl+\都不会被执行,但是当输入任意字符并回车后,原来的信号就会被立即执行.可以先输入任意字符解除SIG_BLOCK状态,然后执行SIG_INT与SIG_QUIT,SIG_INT调用我们自己的函数my_func,所以程序会一直不退出,但是SIG_QUIT仍旧是系统的函数,因此可以正常表达

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <sys/types.h> 
  4. #include <unistd.h> 
  5. #include <signal.h> 
  6.  
  7. void my_func(int signum) { 
  8.     printf("If you want to quit ,please try SIGQUIT\n"); 
  9.  
  10. int main() { 
  11.     sigset_t set, pendset; 
  12.     struct sigaction action1, action2; 
  13.  
  14.     if (sigemptyset(&set) < 0) { 
  15.         perror("sigemptyset"); 
  16.         exit(1); 
  17.     } 
  18.  
  19.     if (sigaddset(&set, SIGQUIT) < 0) { 
  20.         perror("sigaddset"); 
  21.         exit(1); 
  22.     } 
  23.  
  24.     if (sigaddset(&set, SIGINT) < 0) { 
  25.         perror("sigaddset"); 
  26.         exit(1); 
  27.     } 
  28.  
  29.     if (sigismember(&set, SIGINT)) { 
  30.         sigemptyset(&action1.sa_mask); 
  31.         action1.sa_handler = my_func; 
  32.         action1.sa_flags = 0; 
  33.         sigaction(SIGINT, &action1, 0); 
  34.     } 
  35.  
  36.     if (sigismember(&set, SIGQUIT)) { 
  37.         sigemptyset(&action2.sa_mask); 
  38.         action2.sa_handler = SIG_DFL; 
  39.         action2.sa_flags = 0; 
  40.         sigaction(SIGQUIT, &action2, 0); 
  41.     } 
  42.  
  43.     if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) { 
  44.         perror("sigprocmask"); 
  45.         exit(1); 
  46.     } else { 
  47.         printf("Signal set was blocked,Press any key!"); 
  48.         getchar(); 
  49.     } 
  50.     if (sigprocmask(SIG_UNBLOCK, &set, NULL) < 0) { 
  51.         perror("sigprocmask"); 
  52.         exit(1); 
  53.     } else { 
  54.         printf("Signal set is unblock state\n"); 
  55.     } 
  56.     while (1) 
  57.         ; 
  58.     exit(0); 

 

Linux C编程—fork子程序以及fifo有名管道的使用

 

写一个程序,创建一个fifo有名管道,然后利用程序与子程序完成程序间的信息传输实例.

功能:输入什么,输出什么

           输入q或者Q程序退出

调用fifo文件:/tmp/fifo

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4. #include <sys/types.h> 
  5. #include <sys/stat.h> 
  6. #include <errno.h> 
  7. #include <fcntl.h> 
  8. #include <limits.h> 
  9.  
  10. #define FIFO_FILE "/tmp/fifo" 
  11. #define BUFFER_SIZE PIPE_BUF 
  12.  
  13. int main(void) { 
  14.     char buff[BUFFER_SIZE]; 
  15.  
  16.     if (access(FIFO_FILE, F_OK) == -1) { 
  17.         if ((mkfifo(FIFO_FILE, 0666) < 0) && (errno != EEXIST)) { 
  18.             printf("Filo file create error!\n"); 
  19.         } 
  20.     } 
  21.     pid_t newfork = fork(); 
  22.     if (newfork < 0) { 
  23.         printf("Fork error!\n"); 
  24.         exit(1); 
  25.     } else if (newfork == 0) { 
  26.         int fd1 = open(FIFO_FILE, O_RDONLY); 
  27.         int reader; 
  28.         if (fd1 < 0) { 
  29.             printf("child process fd error!\n"); 
  30.             exit(1); 
  31.         } 
  32.         while (1) { 
  33.             reader = read(fd1, buff, BUFFER_SIZE); 
  34.             if ((buff[0] == 'q' && buff[1] == '\0'
  35.                     || (buff[0] == 'Q' && buff[1] == '\0')) { 
  36.                 printf("Get EXIT message and quit!\n"); 
  37.                 close(fd1); 
  38.                 exit(0); 
  39.             } 
  40.             if (reader > 0) { 
  41.                 printf("Read from FIFO:%s\n", buff); 
  42.             } 
  43.         } 
  44.     } else { 
  45.         int fd2 = open(FIFO_FILE, O_WRONLY); 
  46.         int writer; 
  47.         if (fd2 < 0) { 
  48.             printf("Father process fd error!\n"); 
  49.             exit(1); 
  50.         } 
  51.         while (1) { 
  52.             if ((buff[0] == 'q' && buff[1] == '\0'
  53.                     || (buff[0] == 'Q' && buff[1] == '\0')) { 
  54.                 close(fd2); 
  55.                 exit(0); 
  56.             } 
  57.             scanf("%s", buff); 
  58.             writer = write(fd2, buff, BUFFER_SIZE); 
  59.         } 
  60.     }