C - 分段错误(核心转储)

问题描述:

我想写一个简单的C程序,它接受一个数字的输入并返回数字的总和以及数字的反向。该程序目前不完整,因为我在测试时遇到了分段错误错误。C - 分段错误(核心转储)

下面是代码:

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

int sumdigits(int); 

int main() { 
    int num;    // The number to be read 
    int reverse;   // The reverse of the input 
    int sum;    // The sum of the digits 


    printf("Enter a number: "); 
    scanf("%d", &num); 
    sum = sumdigits(num); 
    printf("Sum of digits: %s", sum); 
} 

int sumdigits(int number) { 
    int sum = 0; 
    int temp = number; 
    while (temp != 0) { 
     sum += (temp % 10); 
     temp /= 10; 
    } 
    return sum; 
} 

通过使用一些打印语句,我发现,错误很可能在这些线路的某处发生:

printf("Enter a number: "); 
scanf("%d", &num); 

我能够进入数字,但在此之后,我收到一条消息,说Segmentation Fault(核心转储)并退出程序。使用sudo权限运行该程序只会提供分段错误,而不会消息的“核心转储”部分。

由指令提供

调试信息,随后here似乎表明printf语句是什么原因造成的错误,因为这是输出:

(gdb) run 
Starting program: /home/sschmalz/Documents/Classes/CIS308/proj1/debug 
Enter a number: 123 

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7a62fb4 in vfprintf() from /lib64/libc.so.6 

不过,我不知道该怎么做这信息,所以我无法解决错误。

我已经问过我的教授在实验室中遇到同样的错误,他无法找到解决方案。这现在发生在两个不同的实验室,再加上这个项目,这让我觉得它可能是我的电脑设置而不是代码本身。

我正在编写使用vim和使用gcc编译的程序。在大多数情况下,我不重命名编译器的输出,所以我使用“./a.out”来运行它。我使用Fedora 24来编写和运行这些程序。如果需要关于我的系统的其他信息,请告诉我。

+1

传递一个'int'到'的printf()'用'%s'转换不确定的行为。 – EOF

+0

我的计算机上的编译器出于某种原因没有收到字符串格式错误。我把这个文件上传到我大学的Linux服务器上,并在那里编译,这给了我例外和修复。谢谢大家的帮助,对于这样一个小问题,我觉得自己像个白痴。 –

变化

printf("Sum of digits: %s", sum); 

printf("Sum of digits: %d", sum); 

%s是不是整数的字符串(%d是有符号整数)。

http://www.cplusplus.com/reference/cstdio/printf/

+0

谢谢你指出这一点。出于某种原因,我的计算机上的编译器没有看到这一点,但是当我将其上传到我大学的Linux服务器并编译时,它引发了一个异常。 –

+0

@SamSchmalzried这不是一般会被捕获的东西,因为所有的编译器都需要知道或关心的是'printf()'接受一个任意的字符串和一组可变参数(因此必然是任意的),两者都是你提供了。检查你提供的参数是否合理组合需要大量的杂技 - 并且可能需要运行时检测变量参数idk - 大多数编译器不会浪费时间去做,除非你明确告诉它们。否则,他们只是假设你的论点是有道理的。 –

您已在printf()功能使用不正确的格式说明符,其修改为:

printf("Sum of digits: %d", sum); 

,它会正常工作(%d代表十进制(数字)和%s代表字符串)。

我跑你的代码和它的作品,但你必须改变printf("Sum of digits: %s", sum);要么printf("Sum of digits: %i", sum);printf("Sum of digits: %d", sum);

有使用%d%i中没有差异printf(),因为:

  1. 转换说明符及其含义如下:d,i - int参数转换在样式[ - ] dddd中标记为十进制。精度为 指定要显示的最小位数;如果要转换的值为 可用较少的数字表示,则用前导零扩展为 。默认精度为1. 将精度为零的零值转换为无字符。 来源:C99标准http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

然而,在使用scanf()%d%i因为前者被存储为一个十进制整数,后者为一个整数的差。来源:https://cs50.harvard.edu/resources/cppreference.com/stdio/scanf.html

我跑了代码工作:

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

int sumdigits(int); 

int main() { 
    int num;    // The number to be read 
    int reverse;   // The reverse of the input 
    int sum;    // The sum of the digits 


    printf("Enter a number: "); 
    scanf("%i", &num); 
    sum = sumdigits(num); 
    printf("Sum of digits: %i", sum); 
} 

int sumdigits(int number) { 
    int sum = 0; 
    int temp = number; 
    while (temp != 0) { 
     sum += (temp % 10); 
     temp /= 10; 
    } 
    return sum; 
}