【问题标题】:What is "Segmentation Fault (core dumped)" and why is it being returned in my output?什么是“分段错误(核心转储)”,为什么它会在我的输出中返回?
【发布时间】:2018-10-03 20:01:04
【问题描述】:

我正在尝试将包含重复 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); 已修复。谢谢!

【问题讨论】:

  • 问题应该是独立的(参见minimal reproducible example)。不要发布代码链接,也不要发布代码图片
  • 这意味着您的程序正在尝试读取或写入一个不存在的内存位置。
  • 您的代码甚至不应该编译 charchar* 是两种截然不同的类型。打开所有编译器警告,永远不要忽略它们
  • text 将由\0 而非\n 终止;
  • @Stavr00 fgets() 读取一行并将换行符留在其中,除非该行长于MAX

标签: c fgets getchar strlen


【解决方案1】:

您的错误或至少其中一个错误似乎在以下几行中:

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

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

fgets 的返回值是一个 指向char 的指针,但您将它存储在char 中,然后尝试将char 值传递给一个函数期望 指向 char 的指针。由于char 仅 8 位宽(在您要编译的任何机器上)并且指针需要 32 或 64 位,因此大部分位都会丢失,结果是指针无效。如果幸运的话,这将导致程序因分段错误而崩溃。

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

最简单的解决方法是消除c 并改为写入

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多