QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1521|回复: 20

菜鸟求助:段错误问题!!!!

[复制链接]
发表于 2004-3-7 12:38:26 | 显示全部楼层 |阅读模式
[code:1]
/*setpassword.c */
#include <stdio.h>

int main (int argc, char *argv[])
{
  FILE *InputPasswordFile;
  char Input;
  char InputPassword[33], *pInputPassword = InputPassword;
  int Count;

  printf("请设置您的密码(最长16位):");

  while ((Input = getchar ()) != '\n')
    {
      InputPassword[Count] = Input;
      Count++;
    }
  InputPassword[Count] = '\0';

  if ((InputPasswordFile = fopen ("password.dat", "wb")) == NULL)
    {
      printf("系统错误!\n");
      exit (0);
    }
  else
    printf("密码设置成功!\n");



  fwrite(pInputPassword, sizeof(char), 33, InputPasswordFile);

  fclose(InputPasswordFile);
}


/*password.c */
#include <stdio.h>
#include <string.h>

int *strcmp (const char *s1, const char *s2);

int main (int argc, char *argv[])
{
  char InputPassword[16];
  char GetPassword[16];
  char Input;
  int *Check;
  int Count;
  FILE *GetPasswordFile;

  if ((GetPasswordFile = fopen ("password.dat", "rb")) == NULL)
    {
      printf("密码未设置!\n");
      exit (0);
    }
  
  fread(GetPassword, sizeof(char), 16, GetPasswordFile);


  printf("请输入您的密码:");

  while ((Input = getchar ()) != '\n')
    {
      InputPassword[Count] = Input;
      Count++;
    }
  InputPassword[Count] = '\0';

  if ((Check = strcmp (InputPassword, GetPassword)) == 0)
    printf("密码正确!\n");
  else
    printf("密码错误!\n");

  fclose(GetPasswordFile);

}

[/code:1]

在第一个程序中,InputPassword[33]中的33数字,只要输入小于33的。执行程序时就会出现段错误。

在第二个程序中,GetPassword[16]中的16数字,只要输入大于16的。执行程序就会出现段错误。

为什么??
我的是RH9。0
发表于 2004-3-7 13:34:05 | 显示全部楼层
内存!!!!!!!
建议重新插内存!
回复

使用道具 举报

发表于 2004-3-7 13:38:31 | 显示全部楼层
我不太懂C, 但好像你的int Count都没有初始化. 是不是这个原因啊?
回复

使用道具 举报

发表于 2004-3-7 13:39:56 | 显示全部楼层
[quote:c5eb8a095d="hgty7890"]内存!!!!!!!
建议重新插内存![/quote]

您是在开玩笑还是在说真的?
回复

使用道具 举报

发表于 2004-3-7 20:22:07 | 显示全部楼层

以下代码编译和运行环境为:
rh8.0 kernel2.4.18-14 gcc3.2


1 Count没有设置初值。
不要指望gcc为你设置初值,请看下面代码:
[code:1]
#include <stdio.h>
int main()
{
        int i;
        printf("%d\n",i);
        return 0;
}
[/code:1]
编译运行:
[code:1]
[dengnan@localhost test]$ gcc test.c
[dengnan@localhost test]$ ./a.out
1108517584
[dengnan@localhost test]$
[/code:1]
明白?
2 第二个程序中:
[code:1]int *Check;[/code:1]
但是却有:
[code:1]if ((Check = strcmp (InputPassword, GetPassword)) == 0)[/code:1]
Check里面存储的是地址,这样,如果strcmp (InputPassword, GetPassword)的值为0,那么Check就会指向0(也就是空指针,换句话说就是相当于Check=NULL);
另外还有一些问题,我们慢慢说~
回复

使用道具 举报

发表于 2004-3-7 20:31:21 | 显示全部楼层

看别人代码好费劲啊~~我写了一个,你看看,我的环境下运行正常:
[code:1]
#include <stdio.h>
int main()
{
        FILE *pwfp;
        char pw[33];
        int i;

        memset(pw,0,33);
        pwfp=NULL;

        printf("Input password\n");

        for(i=0;(i<16)&&((pw[i]=getchar())!='\n');i++);
        if(pw[i]=='\n')
                pw[i]=0;

        pwfp=fopen("passwd.dat","w");

        if(NULL==pwfp)
        {
                fprintf(stderr,"Err: can not open passwd.dat\n");
                exit(-1);
        }

        fwrite(pw,sizeof(char),33,pwfp);
        fclose(pwfp);
        return 0;
}


[/code:1]
回复

使用道具 举报

发表于 2004-3-7 20:43:34 | 显示全部楼层
这个是第二个程序:
[code:1]
#include <stdio.h>

int main()
{
        char pw[16];
        char inpw[16];
        int i;
        FILE *pwfp;

        pwfp=NULL;
        memset(pw,0,16);
        memset(inpw,0,16);

        pwfp=fopen("passwd.dat","r");

        if(NULL==pwfp)
        {
                fprintf(stderr,"Err: can not open passwd.dat\n");
                exit(-1);
        }

        fread(pw,sizeof(char),16,pwfp);
        fclose(pw);

        printf("Input password\n");

        for(i=0;(i<16)&&(inpw[i]=getchar())!='\n';i++);
        if(inpw[i]=='\n')
                inpw[i]=0;

        if(0==strcmp(inpw,pw))
                printf("Password matched\n");
        else
        {
                fprintf(stderr,"Failed\n");
                exit(-1);
        }
        return 0;
}
[/code:1]
回复

使用道具 举报

发表于 2004-3-7 20:49:24 | 显示全部楼层

建议:
1 合理使用变量,你的代码中过多的冗余变量,很多变量的任务是相同或者是没有必要的(如:*pInputPassword *Check)
2 变量使用前要赋初值,如果是数组可以采用memset函数或bzero
3 这个语句:

[code:1]
int *strcmp (const char *s1, const char *s2);
[/code:1]

是干什么的???
4 注意指针的使用(推荐文章:鄙人写的《关于指针的学习》就在编程区~:
http://www.linuxfans.org/nuke/modules.php?name=Forums&file=viewtopic&t=36230
)
5 注意检查函数返回值,fread和fwrite的返回值都没有检查( 其实我的代码也没有检查)
6 你的变量和函数的命名方法还是windows上用的匈牙利命名法,个人建议使用UNIX的命名方法
7 出错信息要打印到stderr上
8 再推荐一篇鄙人的文章:
http://www.linuxfans.org/nuke/modules.php?name=Forums&file=viewtopic&t=49801

嗯……就说这么多吧~
hoho~写了三个小东西~推销出了两篇文章~值!!
回复

使用道具 举报

发表于 2004-3-7 21:13:20 | 显示全部楼层
关于匈牙利命名法,我也想说两句。
如果不是很长的变量名,有的时候我也觉得匈牙利命名法挺好读的,lpsz除外。像Password,我经常简写成passwd。既看得懂,又好打。

有一个有趣的例子
Windows API GetCurrentDirectory 与 UNIX API getcwd实现相同的功能。
不过unix里面也有挺让人摸不着头脑的东西:比如kill;第一次看到ps,谁知道是什么东西。
回复

使用道具 举报

发表于 2004-3-7 21:19:45 | 显示全部楼层
这个…………反正我的代码中不会出现类似的代码:
[code:1]
char *strCurrentFileName;
char *last_file_name;
int i;
[/code:1]
回复

使用道具 举报

发表于 2004-3-7 21:22:18 | 显示全部楼层
[quote:89b951add8="默难"]这个…………反正我的代码中不会出现类似的代码:
[code:1]
char *strCurrentFileName;
char *last_file_name;
int i;
[/code:1][/quote]

呵呵
我比较喜欢,MFC程序就用匈牙利,linux或者win32 console,就用unix的风格
回复

使用道具 举报

发表于 2004-3-7 21:32:16 | 显示全部楼层

你不会把匈牙利命名法和UNIX命名法混用吧…………
如果是,建议读读软件工程方面书籍……
回复

使用道具 举报

发表于 2004-3-7 21:41:35 | 显示全部楼层
????

84混用拉!

我一般是遵循框架的命名规则,比如用VCL就用VCL的风格,MFC就用MFC的风格
不过有的时候也挺麻烦?默难, 如果你用MFC的时候用到了STL,你会用哪种风格?
回复

使用道具 举报

发表于 2004-3-7 21:49:16 | 显示全部楼层
1 我不用MFC,即使在windows上编程,我也是使用API,那是以前的事情了,那会理所当然用匈牙利命名法,后来转到Linux上就改用UNIX风格了。自从来到Linux上,我就没再回到windows上编程过……
2 我只用C,不用C++,理所当然不会涉及STL。C++语法学过,并非不喜欢他,也并非对C++有什么偏见,只是觉得C语言用起来更顺手些,OO是发展方向,但并非只有OOL才能写出OO的程序。C语言一样可以写出面向对象的代码,我手头就有一本书叫《OOP in C》。如果不相信,可以看看libpcap的代码
回复

使用道具 举报

 楼主| 发表于 2004-3-7 22:00:19 | 显示全部楼层
这是我的改进的
[code:1]
#include <stdio.h>     /*文件操作及输入输出*/
#include <string.h>    /*字符串比较strcmp*/
#define MAX 100        /*设置密码长度 */

void setpassword (void);  /*设置密码函数*/
void password(void);      /*检验密码函数*/
void function(void);

int *strcmp(const char *s1, const char *s2);  /*字符串比较函数 */

int main(int argc, char *argv[])           /*主函数 */
{
  FILE *FileCheck;        /*检查密码文件函数 */

  if ((FileCheck = fopen ("password.dat", "rb")) == NULL)
    {
      printf("发现程序密码为空,本程序要输入密码才可以运行!\n");
      setpassword();   /*如果找不到密码文件,就调用设置密码函数 */
    }
  else
    {
      password();  /*找到就调用密码检验函数*/
    }
  return 0;
}

void setpassword(void)
{
  FILE *SetFile;                   /*建立密码文件  */
  char SetPassword[MAX], *pSetPassword = SetPassword;  /*建立密码*/
  char CheckPassword[MAX], *pCheckPassword = CheckPassword;  /*确认密码*/
  int *CheckPassword1;
  int Count1 = 0;
  system("stty -echo");  /*屏蔽屏幕输出  */
  
  printf("\n请输入密码:");
  scanf("%s", pSetPassword);
  printf("\n请确认密码:");
  scanf("%s", pCheckPassword);

  if ((CheckPassword1 = strcmp (SetPassword, CheckPassword)) == 0)
    printf("\n密码符合! :)\n");   /*请看strcmp函数定义*/
  else
    {
      printf("\n密码不符合!! :(\n");
      system("stty -cbreak echo");  /*恢复屏幕输出*/
      exit (0);  /*推出程序 */
    }
  
     
  if ((SetFile = fopen ("password.dat", "wb")) == NULL) /*建立文件 */
  {
    printf("系统错误!\n @_@");
    exit (0);
  }
  else
    printf("密码设置成功! ^_^\n");

  system("stty -cbreak echo");

  
  fwrite(pSetPassword, sizeof(char), MAX, SetFile); /*写入文件 */
  fclose (SetFile);  /*关闭文件 */
}


void password (void)
{
  FILE *GetPasswordFile;
  char GetPassword[MAX], *pGetPassword = GetPassword;
  char ComparePassword[MAX], *pComparePassword = ComparePassword;
  int *CheckPassword2;
  int Times = 0;
  
  if ((GetPasswordFile = fopen ("password.dat", "rb")) ==NULL)
    {
      printf("\n密码未设置! 6_6\n");
      exit (0);
    }

  fread(pGetPassword, sizeof(char), MAX, GetPasswordFile);

  
    while (Times <3)      /*设置密码出错次数*/
    {
  
      system ("stty -echo");

      printf("\n请输入您的密码:");
      scanf("%s", pComparePassword);

      
      if ((CheckPassword2 = strcmp(GetPassword, ComparePassword)) == 0)
        {
          printf ("\n密码正确!\n");
          system ("stty -cbreak echo");
          printf ("\n谢谢您的使用.by lluct @^_^@\n");
          function();
          exit (0);
        }
      else
        printf("\n密码错误!!! 8_8\n");
      Times++;
    }
  fclose(GetPasswordFile);
}

void function(void)
{
  int choose;
  printf("%s\n%s",
         "\n1:修改密码  2:打开光驱  3:关闭光驱\n",
         "请选择:");
  scanf("%d", &choose);
  switch (choose)
    {
    case 1:
      setpassword();
      break;
    case 2:
      system("eject -r&");
      break;
    case 3:
      system("eject -t&");
      break;
    default:
      printf("选择错误!! #_#\n");
    }
}
[/code:1]

前辈的程序我会有些变量还是看不懂。但我会去研究的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 20:28 , Processed in 0.063892 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表