我收到了SegFault错误,但为什么?

时间:2016-08-12 02:31:23

标签: c linux

运行代码时出现Segmentation Fault错误,但除此之外,它编译并运行。如果您知道错误发生的原因,我将非常感谢您的帮助。另外,请解释为什么它正在发生,因为我很好奇。

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

int main()
{
    float att,def,hp,agi,stl,wis,ran,acc;
    char name[10],contents[100];
    int warrior,lvl=1,kills=0;

    printf("What is your name?\n");
    gets(name);

    printf("1: Ninja\n");
    printf("2: Knight\n");
    printf("3: Archer\n\n");
    printf("Pick a warrior.\n");
    scanf("%i",warrior);

    ...

    char attack[10],defense[10],health[10],agility[10],stealth[10],wisdom[10],range[10],accuracy[10],level[10],kill[10];
    snprintf(attack,10,"%f",att);
    snprintf(defense,10,"%f",def);
    snprintf(health,10,"%f",hp);
    snprintf(agility,10,"%f",agi);
    snprintf(stealth,10,"%f",stl);
    snprintf(wisdom,10,"%f",wis);
    snprintf(range,10,"%f",ran);
    snprintf(accuracy,10,"%f",acc);
    snprintf(level,10,"%f",lvl);
    snprintf(kill,10,"%f",kills);   

    char my_path[25];
    strcat(my_path,"Warriors/");
    strcat(my_path,name);
    strcat(my_path,".txt");


    FILE *fp;
    fp = fopen(my_path, "w+");

    fputs(attack, fp);
    fputs(" ", fp);
    fputs(defense, fp);
    fputs(" ", fp);
    fputs(health, fp);
    fputs(" ", fp);
    fputs(agility, fp);
    fputs(" ", fp);
    fputs(stealth, fp);
    fputs(" ", fp);
    fputs(wisdom, fp);
    fputs(" ", fp);
    fputs(range, fp);
    fputs(" ", fp);
    fputs(accuracy, fp);
    fputs(" ", fp);
    fputs(level, fp);
    fputs(" ", fp);
    fputs(kill, fp);

    fclose(fp);
}

4 个答案:

答案 0 :(得分:2)

代码中存在以下问题。

  1. 在读取scanf的值时错误地使用warrior

    /* scanf("%i",warrior); */ // Put '&' before warrior
    scanf("%i",&warrior);
    
  2. 打印整数snprintflvl的值时,kills中的格式说明符不正确。

    /* snprintf(level,10,"%f",lvl); */ // Change %f to %d
    snprintf(level,10,"%d",lvl);
    /* snprintf(kill,10,"%f",kills); */ // Change %f to %d
    snprintf(kill,10,"%d",kills); 
    
  3. strcat使用my_path而不初始化。

    /* char my_path[25]; */ // Initialize as seen below 
    char my_path[25] = ""; 
    strcat(my_path,"Warriors_");
    strcat(my_path,name);
    strcat(my_path,".txt");
    
  4. 最后,您使用的是gets,应该避免使用。您可以将其更改为fgets

  5. 现在说明你的程序崩溃的原因。

    首先执行scanf("%i",warrior);时:您提供了&warrior变量的值,而不是地址(即warrior)。由于warrior未初始化,因此它具有不确定的值。现在scanfwarrior的值视为地址并尝试在那里写入值。并且,由于warrior的值是不确定的,因此它调用了未定义的行为。

    第二次在%f中使用%d而不是snprintf(格式说明符不匹配)时,代码再次调用了未定义的行为。

    第三,当您在未初始化strcat的情况下使用my_path时,您的数组my_path将具有不确定的值。现在,strcat0指向的地址开始查找值my_path并继续查看,直到它找到0。在执行此操作时,它可能会尝试读取数组外部的值,再次调用未定义的行为。

    当调用未定义的行为时,任何事情都可能发生。在您的情况下,您遇到了分段错误。

    P.S。:您还应该检查scanf的返回值,以检查它是否成功。

    P.S。:您还应该检查fopen的返回值,以检查它是否成功。

答案 1 :(得分:1)

scanf("%i",warrior);

scanf需要一个指针。 http://linux.die.net/man/3/scanf

将其修复为

scanf("%i", &warrior);

答案 2 :(得分:0)

你最好还添加这种代码来检查fopen是否成功。

john doe<br>jane doe<br>

答案 3 :(得分:0)

这两行:

char my_path[25];
strcat(my_path,"Warriors/");

不正确,因为strcat()函数附加到当前字符串的末尾(它找到了NUL字符&#39; \ 0&#39;)

无法确定NUL char的位置。

建议使用:

char my_path[25];
strcpy(my_path,"Warriors/");