windows程序移植到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中既有这两个函数,可以直接调用

  • 在linux下,没有这两个函数,所以需要自己手写这两个函数

    我们可以写一个conio.h 和conio.c 文件


//conio.c
#include "conio.h"
#include

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 
#include 

char getch();

char getche();

#endif

在运行程序的时候把conio.h这个头文件包含进去就可以了

3.头文件包含不同
  • 比如sleep函数,在windows下要求的头文件是#include
    在linux下要求的头文件是#include
    access函数,在windows下要求的头文件是#include
    在linux下要求的头文件是#include
  • 所以一定要注意特定函数在不同系统下的使用,但其实利用makefile检错会自动显示出错误
4.乱码问题
  • windows下默认的中文编码方式是GBK
    而linux下的默认的中文编码方式是UTF-8
    所以可以在终端下修改编码方式解决这一问题
  • 乱码问题确实足够的让人头疼,在windows下明明可以正常输出,但是转到linux下突然不能正常显示了,这问题搞了一中午,还是没能很好的解决
    暂时只能借助终端改变不同的编码方式
    改好了所有的问题,最终运行程序显示的结果是这样
    windows程序移植到linux的方式和会遇到的问题_第1张图片
    在终端下点击右键,选择编码方式,找到需要的结果
    windows程序移植到linux的方式和会遇到的问题_第2张图片
    这下终于好了
    windows程序移植到linux的方式和会遇到的问题_第3张图片

虽然还没完美解决,以后有了更好的方式再更新吧

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
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);

你可能感兴趣的:(windows程序移植到linux的方式和会遇到的问题)