什么是“分段错误(核心已转储)”,为什么它在我的输出中返回?

时间:2018-10-03 20:01:04

标签: c fgets getchar strlen

我正在尝试通过对fgets的一次调用来替换包含重复的getchar调用的循环

当我尝试输入时,我遇到了Segmentation Fault(核心故障),我不知道那是什么或为什么得到它。

入门代码

/* Example: analysis of text */

#include <stdio.h>
#include <string.h>

#define MAX 1000 /* The maximum number of characters in a line of input */

main()
{
  char text[MAX], c;
  int i;
  int lowercase, uppercase, digits, other;
  int length;

  puts("Type some text (then ENTER):");

  /* Save typed characters in text[]: */
  // In ex1.c, please implement the following loop with fgets() and use strlen() to compute the length of the string
  //
  for (i = 0; i < MAX; i++)
  {
    text[i] = getchar();
    if (text[i] == '\n')
      break;
  }
  length = i;

  /* Analyse contents of text[]: */

  for (i = lowercase = uppercase = digits = other = 0; i < MAX; i++)
  {
    c = text[i];
    if (c >= 'a' && c <= 'z')
      lowercase++;
    else if (c >= 'A' && c <= 'Z')
      uppercase++;
    else if (c >= '0' && c <= '9')
      digits++;
    else
    {
      if (c == '\n')
        break;
      other++;
    }
  }

  puts("\nYou typed:");
  printf("A string with %d characters\n", length);
  printf("\t%d lower case letters\n", lowercase);
  printf("\t%d upper case letters\n", uppercase);
  printf("\t%d digits\n", digits);
  printf("\t%d others\n", other);
}

入门代码测试

Type some text (then ENTER):
asd213qaIW

You typed:
A string with 10 characters
    5 lower case letters
    2 upper case letters
    3 digits
    0 others

我的代码

/* Example:  analysis of text */
#include <stdio.h>
#include <string.h>
#define MAX 1000 /* The maximum number of characters in a line of input */

main()
{
  char text[MAX], c;
  int i;
  int lowercase, uppercase, digits, other;
  int length;

  puts("Type some text (then ENTER):");

  /* Save typed characters in text[]: */
  // In ex1.c, please implement the following loop with fgets() and use strlen() to compute the length of the string
  //
  c = fgets(text, MAX, stdin);
  length = strlen(c);

  /* Analyse contents of text[]: */

  for (i = lowercase = uppercase = digits = other = 0; i < MAX; i++)
  {
    c = text[i];
    if (c >= 'a' && c <= 'z')
      lowercase++;
    else if (c >= 'A' && c <= 'Z')
      uppercase++;
    else if (c >= '0' && c <= '9')
      digits++;
    else
    {
      if (c == '\n')
        break;
      other++;
    }
  }

  puts("\nYou typed:");
  printf("A string with %d characters\n", length);
  printf("\t%d lower case letters\n", lowercase);
  printf("\t%d upper case letters\n", uppercase);
  printf("\t%d digits\n", digits);
  printf("\t%d others\n", other);
}

我的代码测试

Type some text (then ENTER):
asd213qaIW  
Segmentation fault (core dumped)

我们将不胜感激。
我对C还是很陌生,所以如果您能尽可能简单地解释一下。

更改 length = strlen(c); length = strlen(text); 已修复。谢谢!

1 个答案:

答案 0 :(得分:0)

您的错误或至少其中之一,出现在以下几行中:

char text[MAX], c;
// ...

c = fgets(text, MAX, stdin);
length = strlen(c);

fgets的返回值是指向 char的指针,但是您将其存储在char中,然后尝试传递{{ 1}}的值赋予期望指针 char的函数。由于char只有8位宽(在要编译的任何计算机上),并且指针需要32位或64位,因此大多数位都丢失了,结果是指针无效。如果幸运的话,这会使程序崩溃并出现段错误。

此代码实际上根本不应该编译。如果您至少没有收到警告char不能保持指向指针 c的警告,则需要打开更多警告标志。 (在chargcc上,我通常使用clang进行编译。)然后,至少在您学习该语言时,请将收到的任何警告都视为程序中的错误。更好的是,添加-std=c99 -Wall -Wextra -Wpedantic -Wconversion(或与您的编译器等效的文件)以使编译器以这种方式对待它们。

最简单的解决方法是消除-Werror并改写

c