【问题标题】:two codes working fine in separate program but the program crashing while the codes are in the same program两个代码在单独的程序中运行良好,但是当代码在同一个程序中时程序崩溃
【发布时间】:2012-07-20 16:04:37
【问题描述】:

嘿,这段代码正在运行。该代码是关于获取名称输入并对其进行一些更改。

#include <stdio.h>
#include <stdlib.h>

/*
 *  An example of how to use strtol() to read a number
 *  and validate that one was entered correctly.
 *
 */

int main(void)
{
  char buf[BUFSIZ];
  char *p;
  long int i;

  printf ("Enter a number: ");

  if (fgets(buf, sizeof(buf), stdin) != NULL)
  {
    i = strtol(buf, &p, 10);

    /*
     *  If the first character of the buffer is \n, the user
     *  pressed [Enter] with entering any text at all, which
     *  is therefore invalid.
     *
     *  The pointer p has been updated by strtol() to point to
     *  the first invalid character after the number.
     *  If this character is \0 it means we reached the end of
     *    the array successfully, so we received a good number.
     *  If this character is \n it also means we reached the
     *    end of the input successfully.  This is a symptom of
     *    using fgets() to obtain the string, but does not
     *    represent a problem.
     *  If this character is anything else, it means there was
     *    some additional characters entered after the number.
     *    In this sample program, I have deemed this situation
     *    to be invalid, however, in your program it may be
     *    valid, depending on what you're expecting from the user.
     *
     */

    if (buf[0] != '\n' && (*p == '\n' || *p == '\0'))
      printf ("Valid number of %ld entered\n", i);
    else  printf ("Invalid number entered\n");
  }

  return(0);
}

这段代码也可以工作!它需要一个字符串并转换为一个整数!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    int m;
    char name[m],rename[m],c=0,j=0;
    puts("enter your name\n");
    gets(name);
    m=strlen(name);
    if(m>20){
        while(m>20){
            puts("shorter name pls\n");
            gets(name);
            m=strlen(name);
        }
    }
    while(name[c]==' '){
        c++;}
    while(c<strlen(name)){
        if(name[c]==' '&& name[c+1]==' ')
            {c++;}
        else{
            rename[j]=name[c];
            j++;
            c++;}
    }
    rename[j]='\0';
    puts(rename);
    return 0;
}

但是在同一个程序中同时输入它们时,程序崩溃了!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    int m;
    char name[m],rename[m],c=0,j=0;
    puts("enter your name\n");
    gets(name);
    m=strlen(name);
    if(m>20){
        while(m>20){
            puts("shorter name pls\n");
            gets(name);
            m=strlen(name);
        }
    }
    while(name[c]==' '){
        c++;}
    while(c<strlen(name)){
        if(name[c]==' '&& name[c+1]==' ')
            {c++;}
        else{
            rename[j]=name[c];
            j++;
            c++;}
    }
    rename[j]='\0';
    puts(rename);
      char buf[BUFSIZ];
  char *p;
  long int i;

  printf ("Enter a number: ");

  if (fgets(buf, sizeof(buf), stdin) != NULL)
  {
    i = strtol(buf, &p, 10);

    /*
     *  If the first character of the buffer is \n, the user
     *  pressed [Enter] with entering any text at all, which
     *  is therefore invalid.
     *
     *  The pointer p has been updated by strtol() to point to
     *  the first invalid character after the number.
     *  If this character is \0 it means we reached the end of
     *    the array successfully, so we received a good number.
     *  If this character is \n it also means we reached the
     *    end of the input successfully.  This is a symptom of
     *    using fgets() to obtain the string, but does not
     *    represent a problem.
     *  If this character is anything else, it means there was
     *    some additional characters entered after the number.
     *    In this sample program, I have deemed this situation
     *    to be invalid, however, in your program it may be
     *    valid, depending on what you're expecting from the user.
     *
     */

    if (buf[0] != '\n' && (*p == '\n' || *p == '\0'))
      printf ("Valid number of %ld entered\n", i);
    else  printf ("Invalid number entered\n");
  }
    return 0;
}

为什么??

【问题讨论】:

    标签: c crash


    【解决方案1】:

    当然这是非常错误的:

    int m;
    char name[m],rename[m],c=0,j=0;
    

    您正在声明长度为未初始化变量的数组。

    【讨论】:

    • 好吧,我认为这不是问题。我使用代码块 10.05,它允许我使用未初始化的变量声明数组。我告诉程序的每个部分都可以很好地单独工作,但不能一起工作..!
    • 我妈妈允许我声明未初始化大小的数组,但这并不意味着她是对的。未初始化的变量可以是任何东西,特别是它们的值可能因运行而异,或者在添加/删除代码时会发生变化。后者可能是为什么它在一种情况下对你有用,而不是另一种。
    【解决方案2】:

    即使在您将两者合并之前,此程序中也有几处看起来不太好。

    • 第 7 行:您声明了一个大小未定义的数组。
    • 第 18 行:“名称”下标索引 c 是一个字符 - 限制为 0..127。 int 会更好。
    • 第 24 行:c 和 j 相同。

    然后,应该避免使用 gets() 函数,因为它可能会向它提供比它准备接受的更多的数据,从而使你的程序崩溃。如果 m 被初始化为零,任何长度的任何输入都可能引发崩溃。

    更改第一行使其生效:

    int m = 100;
    char name[m],rename[m];
    int c=0,j=0;
    

    ...但是如果您输入的名称比 m 长,您将再次崩溃。

    如果名称长于 m 和 127 中的较小者,仅设置 m 的值会导致崩溃。假设您有 m = 200 并输入包含 130 个空格的名称:那么这一行

    while(name[c]==' '){ c++;}

    会增加 c 直到它是 126,然后是 127,然后发现 name[127] 是一个空格会再次增加 c。但是 c 是一个字符,因此 c+1 不是 128,而是 -128。当转换为内存地址以索引“名称”时,-128 指向外层空间的某个地方,程序将陷入困境。

    提示:当您编译程序并且还不是专家时,请将所有编译器警告保持在最高设置。当您成为专家时,您将能够关闭它们——并且学会了不想这样做:-)。

    GCC 在你的第一个来源上运行说:

    In function ‘main’:
    18:5: warning: array subscript has type ‘char’ [-Wchar-subscripts]
    20:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    21:9: warning: array subscript has type ‘char’ [-Wchar-subscripts]
    24:13: warning: array subscript has type ‘char’ [-Wchar-subscripts]
    24:13: warning: array subscript has type ‘char’ [-Wchar-subscripts]
    28:5: warning: array subscript has type ‘char’ [-Wchar-subscripts]
    7:5: warning: ‘m’ is used uninitialized in this function [-Wuninitialized]
    warning: the `gets' function is dangerous and should not be used.
    

    【讨论】:

    • 好吧,我认为这不是问题。我使用代码块 10.05,它允许我使用未初始化的变量声明数组。我告诉程序的每个部分都可以很好地单独工作,但不能一起工作..!
    • 使用未初始化的内存是有风险的。它是不确定的。根据您的其他操作,它可能会起作用......或者它可能会崩溃。我想代码块(和大多数 IDE)可以让你写: free(a = malloc(1024)); memcpy(a, otherFunction(), 1024); - 这将适用于 otherFunction() 的大多数实现。然后,有一天你在 otherFunction 中添加一个 fopen() 或类似的东西;程序爆炸了。所以你说,“fopen 一定有问题:因为,没有 fopen,它可以工作!”。但问题出在一个洞里,它掉进洞里是偶然的。
    【解决方案3】:

    “崩溃”是什么意思?提前终止?有什么错误?程序应该做什么?

    还要注意,gets() 永远不应该在实际代码中使用。

    【讨论】:

    • 提前终止..!没有给出错误,但程序在任何事情发生之前终止!
    猜你喜欢
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2014-01-17
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    相关资源
    最近更新 更多