写sfss时遇到的问题

来源:互联网 发布:江苏软件考试网 编辑:程序博客网 时间:2024/04/16 14:52

1.控制输入字符串的长度

 fgets(admin,NAME_LENGH,stdin);

 if(admin[strlen(admin)-1]=='\n')

            admin[strlen(admin)-1]='\0'; 

fflush(stdin);//The ANSI/ISO standard specifies that fflush() is useful only on OUTPUT streams

2. scanf 不读入回车,所以会将回车遗留在缓冲区

 fgets(tempbuf,sizeof(tempbuf),stdin);                                                    
 while(strcmp(tempbuf,"\n")==0)  //将遗留在缓冲区中的回车或者用户输入的回车放弃                       
     fgets(tempbuf,sizeof(tempbuf),stdin);  

3.清除输入缓冲--若本身缓冲区是空的就一直等待输入

int c;

while( (c=getchar()) !='\n'  && c!=EOF);

-------------------------------------------------

fflush(stdin);   //清空输入流!!!!linux 下不行

fflush(stdout); //清空输出流


--------------------------------------------------------------------------

.图形化固定位置输入输出curses.h

.printf 一般要有\n或者缓冲区满了才输出到屏幕,导致数据不能及时显示在屏幕上,所有可以write(STANDOUT_FILENO,str,len)来代替printf

.退格在屏幕上显示“^H”:system("stty erase ^H") 可以删除字符不显示^H,但是一直按退格会一直删除字符,包括不是刚刚用户输入的不应该删除的提示字符,

或者用tcgetattr、tcsetattr函数设置修改键盘动作,控制退格删除字符

--------------------------------------------------------

4.写文件后没有close,中断ctrl+c,写的文件不会保存

5.逗号运算
假设b=2,c=7,d=5,
  a1=(++b,c--,d+3);
  a2=++b,c--,d+3;
  对于第一行代码,有三个表达式,用逗号分开,所以最终的值应该是最后一个表达式的值,也就是d+3,为8,所以a1=8。
  对于第二行代码,那么也是有三个表达式,这时的三个表达式为a2=++b、c--、d+3,(这是因为赋值运算符比逗号运算符优先级高)所以最终表达式的值虽然也为8,但a2=3。-http://blog.sina.com.cn/s/blog_693d42fc01010ytm.html

C 语言中,逗号(,)也可以是运算符,称为逗号运算符(Comma Operator)。逗号运算符可以把两个以上(包含两个)的表达式连接成一个表达式,称为逗号表达式。其一般形式为:
子表达式1, 子表达式2, ..., 子表达式n
例如:
a + b, c = b, c++
逗号运算符的优先级是所有运算符中级别最低的,通常配合 for 循环使用。逗号表达式最右边的子表达式的值即为逗号表达式的值。上例中,c++ 的值(c 自增之前的值)即为该表达式的值。
逗号运算符保证左边的子表达式运算结束后才进行右边的子表达式的运算。也就是说,逗号运算符是一个序列点,其左边所有副作用都结束后,才对其右边的子表达式进行运算。因此,上例中,c 得到 b 的值后,才进行自增运算。


6.动态分配内存:http://blog.csdn.net/firecityplans/article/details/4490124

void *malloc(unsigned size)//动态申请size个字节的内存空间;功能:在内存的动态存储区中分配一块长度为" size" 字节的连续区域。函数的返回值为该区域的首地址。。(类型说明符*)表示把返回值强制转换为该类型指针。

(void *)calloc(unsigned n,unsigned size)//      用于向系统动态申请n个, 每个占size个字节的内存空间; 并把分配的内存全都初始化为零值。函数的返回值为该区域的首地址

(void *)realloc(void *p,unsigned size)//将指针p所指向的已分配内存区的大小改为size

区别:两者都是动态分配内存。主要的不同是malloc不初始化分配的内存,已分配的内存中可以是任意的值. calloc 初始化已分配的内存为0。


内存拷贝函数原型:void *memcpy(void *dest, const void *src, size_t n);
功能:
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中


6.socket 的问题:http://blog.csdn.net/rstevens/article/details/3284661

a. Connection reset by peer
如果调用 read() 从 TCP 连接上接收数据并返回 -1,且 errno 为 104(Connection reset by peer);这通常表示对端程序没有关闭 socket 就直接退出了 (例如 core dump );
正常调用 close() 来关闭一个 socket, 会导致关闭连接的两次握手过程,这需要一点网络交互时间;这种情况下, read() 返回的是 0。
如果对端程序没有显式调用 close() 来关闭一个 TCP 连接,那么在进程退出前,操作系统会释放相关的资源,包括关闭打开的文件描述符;但是这种情况下的关闭,只是发送一个 RESET 包就立刻结束,因此 read() 返回 -1 且 errno 为 104。
因此,在开发过程中,遇到这种现象,可以判断对端程序是不是出了问题。

当线程a一直在read() 一个close()了的socket,则一直返回0。

当你再启动一个线程b,一对套接字与线程a通信时,特别是不断给对方write发送数据时,write可能返回-1, errno 为 104(Connection reset by peer)。这时可能是线程a一直在read() 一个close()了的socket(不是线程a与b之间建立的新的套接字)造成的,只要停止线程a中的read就可以了-------不知道为什么
b. write() 调用返回 -1 且 errno 为 EAGAIN
当在一个非阻塞的 socket 上调用 write(),可能会出现上述现象。
在非阻塞的 socket 上, write() 操作仅仅把数据送入内核空间的 buffer 就立刻返回;如果 socket 在内核空间中对应的 buffer 已满,就会出现这种现象。

有两种处理方式:
第一种比较简单,就是在稍后重新发送数据
第二种是通过 selecet(), poll() 等系统调用,在得到 socket 可写的通知时,再去发送数据


c.与一个disconnected socket 通信,底层会抛出一个SIGPIPE信号(对方进程退出了,你write一次给他,你会收到rst段,再write给他,你会收到sigpipe信号;对方进程退出了没close,他系统会关闭所有的文件描述,即系统会关闭套接字,并发送一个 RESET 包给你, read() 会返回 -1 且 errno 为 104-Connection reset by peer)。可以用来判断对方是否在线

signal(SIGPIPE,receivePipBroken);

void receivePipBroken(int sign_no)
{
if(sign_no == SIGPIPE)
{
printf("a client exit!\n");
CurrentClientNum --;
pthread_exit(0);
}
}



0 0
原创粉丝点击