windows程序移植到linux的方式和会遇到的问题
windows程序移植到linux的方式和会遇到的问题怎么移植写一个makefile文件足矣解决这些问题,执行make在结果中去找问题,外加修改即可,所以就不过多的赘述了移植时可能遇到的问题以下是我在移植时遇到的问题1.sleep函数2.getch()和getche()函数在linux下不兼容3.头文件包含不同4.乱码问题5.对于缓冲区的控制6.如该程序需要输入密码,linux如何控制回显和退格删
windows程序移植到linux的方式和会遇到的问题
怎么移植
写一个makefile文件足矣解决这些问题,执行make在结果中去找问题,外加修改即可,所以就不过多的赘述了
移植时可能遇到的问题
以下是我在移植时遇到的问题
1.sleep函数
2.getch()和getche()函数在linux下不兼容
3.头文件包含不同
4.乱码问题
5.对于缓冲区的控制
6.如该程序需要输入密码,linux如何控制回显和退格删除错误字符
7.gets函数的危险性
1.sleep函数
- 在windows中
Sleep(2*1000); //睡眠两秒
- 在linux中
sleep(2); //睡眠两秒
所以一定要注意在不同系统下函数参数有可能不一样,移植到linux中一定要修改,否则很难查找
2.getch()和getche()函数在linux下不兼容
-
函数功能:getch()函数不将读入的字符回显在显示屏幕上, 而
getche() 函数却将读入的字符回显到显示屏幕上。 -
在windows下,头文件#include<stdio.h>中既有这两个函数,可以直接调用
-
在linux下,没有这两个函数,所以需要自己手写这两个函数
我们可以写一个conio.h 和conio.c 文件
//conio.c
#include "conio.h"
#include<stdio.h>
char getch()
{
char c;
system("stty -echo"); //不回显
system("stty -icanon");//设置一次性读完操作,如使用getchar()读操作,不需要按enter
c=getchar();
system("stty icanon");//取消上面的设置
system("stty echo");//回显
return c;
}
char getche()
{
char c;
system("stty -icanon");
c=getchar();
system("stty icanon");
return c;
}
//conio.h
#ifndef _CONIO_H
#define _CONIO_H
#include <stdio.h>
#include <stdlib.h>
char getch();
char getche();
#endif
在运行程序的时候把conio.h这个头文件包含进去就可以了
3.头文件包含不同
- 比如sleep函数,在windows下要求的头文件是#include<windows.h>
在linux下要求的头文件是#include<unistd.h>
access函数,在windows下要求的头文件是#include<io.h>
在linux下要求的头文件是#include<unistd.h> - 所以一定要注意特定函数在不同系统下的使用,但其实利用makefile检错会自动显示出错误
4.乱码问题
- windows下默认的中文编码方式是GBK
而linux下的默认的中文编码方式是UTF-8
所以可以在终端下修改编码方式解决这一问题 - 乱码问题确实足够的让人头疼,在windows下明明可以正常输出,但是转到linux下突然不能正常显示了,这问题搞了一中午,还是没能很好的解决
暂时只能借助终端改变不同的编码方式
改好了所有的问题,最终运行程序显示的结果是这样
在终端下点击右键,选择编码方式,找到需要的结果
这下终于好了
虽然还没完美解决,以后有了更好的方式再更新吧
5.对于缓冲区的控制,具体见7
- 在输入密码的时候要特别注意缓冲区,例如下面的代码部分
//这是该系统刚进入去输入账户和密码的代码
for (i = 0; i < 3; i++) {
printf("\n\n\n\n\t\t\t\t\t");
printf("\n\n\t\t\t\t\t 南波万剧院票务管理系统\n");
printf("\n\n\t\t\t\t\t\t账号: ");
scanf("%[^\n]",usrname); //读取账户
fflush(stdin);
printf("\n\t\t\t\t\t\t密码: ");
int ret = GetPassword(passwd); //获取密码
用scanf去读取账户名,回车结束输入账户名,这时回车就会被加入到缓冲区,当利用GetPassword获取密码时,第一个字符就成了回车,所以需要用fflush去冲刷缓冲区,利用getch也可以
6.如该程序需要输入密码,linux如何控制回显和退格删除错误字符
int GetPassword(char password[])
{
char ch;
int i;
for(i=0;i<20;i++){
ch=getch();
if(ch== 8){
if((i-1)>=0){
i-=2;
printf("\b\b \b\b");
}
else
i--;
continue;
}
if(ch == '\n')
break;
password[i]=ch;
printf("*");
}
password[i]='\0';
return i;
}
在windows下,这是可以正常执行删除的,但是在linux下会正常读取退格键,并输入密码,
//解决不能使用退格键的方案
int GetPassword(char* passwd)
{
int c;
int n = 0;
do
{
c=getch();
if (c != '\n'&& c!='\r' && c!=127)
{
passwd[n] = c;
printf("*");
n++;
}
else if ((c != '\n'|c!='\r')&&c==127)//判断是否是回车或者是退格
{
if(n>0)
{
n--;
printf("\b \b");//输出退格
}
}
}while(c != '\n' && c !='\r' );
passwd[n] = '\0'; //消除一个多余的回车
return n;
}
7.gets函数的危险性,scanf读数据不干净!!!
scanf在读完之后空格还在缓冲区中
gets函数能够接收字符串和空格, 而且不把回车符号留在缓存区中,但是会读取\n
#include<stdio.h>
int main(void)
{
char a1[10],a2[10],a3[10];
scanf("%s",a1);
gets(a2);
gets(a3);
puts(a1);
puts(a2);
puts(a3);
printf("end...");
return 0;
}
输入: |输入:
qwe asd |abc
zxc |def
结果: |ghi
qwe |abc
asd |
zxc |def
end... |end...
//因为scanf把回车 / 空格 扔进了缓冲区,所以在第二次输入ghi被丢弃
由于gets不会检查越界,所以不安全,gets 函数里面输入的字符串过长也会出现直接崩溃的情况。
一般换做更为安全的fgets函数或scanf函数(格式改为可接受空格)
char buf[30];
scanf("%[^\n]",buf); //读入一行字符串带空格的字符
fgets(buf,30,stdin);
更多推荐
所有评论(0)