Что такое «Ошибка сегментации (ядро сброшено)» и почему он возвращается в моем выводе? - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь заменить цикл, содержащий повторяющиеся вызовы getchar, одним вызовом fgets

Когда я пытаюсь ввести ввод, я получаю ошибку сегментации (сбрасывается ядро), и я не знаю, что это такоеили почему я его получаю.

Код стартера

/* 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 голосов
/ 05 октября 2018

Ваша ошибка или хотя бы одна из них, по-видимому, содержится в следующих строках:

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

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

Возвращаемое значение fgets - это указатель на char, но вы сохраняете его в char и затем пытаетесь передать значение char в функцию, которая ожидает указатель на char.Поскольку char имеет ширину всего 8 бит (на любом компьютере, на котором вы будете компилировать), и указателю требуется 32 или 64 бита, большая часть битов теряется, и в результате получается неверный указатель.Это, если вам повезет, приведет к сбою программы с ошибкой сегментации.

Этот код действительно не должен был компилироваться вообще.Если вы не получили хотя бы предупреждение о том, что c не может удерживать указатель на char, вам необходимо включить дополнительные флаги предупреждения.(На gcc или clang я обычно компилирую с -std=c99 -Wall -Wextra -Wpedantic -Wconversion.) Затем, по крайней мере, пока вы изучаете язык, воспринимайте любое предупреждение, которое вы получаете, как ошибку в вашей программе.А еще лучше, добавьте -Werror (или эквивалент для вашего компилятора), чтобы компилятор относился к ним таким образом.

Самое простое решение - исключить c и написать вместо него

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