两个代码在单独的程序中工作正常,但程序崩溃,而代码在同一个程序中

时间:2012-07-20 16:04:38

标签: c crash

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

#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;
}

为什么?

3 个答案:

答案 0 :(得分:2)

当然这是非常错误的:

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

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

答案 1 :(得分:1)

有些事情在这个程序中看起来不太好,甚至在你合并这两个之前。

  • 第7行:您声明一个未定义大小的数组。
  • 第18行:'name'下标索引c是char - 限制为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,然后发现该名称[127]是一个空格会再次增加c。但是c是一个char,因此c + 1不是128,而是-128。当转换为内存地址以索引'name'时,-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.

答案 2 :(得分:0)

你是什么意思'崩溃'?提前终止?有什么错误?该计划应该做什么?

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