Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 带字符串的分段错误(堆芯转储)_C - Fatal编程技术网

C 带字符串的分段错误(堆芯转储)

C 带字符串的分段错误(堆芯转储),c,C,我必须写一个函数,它得到30个没有重复名称的名称,然后在这30个名称上随机打印。但当我在输入第二个名字后运行程序时,出现了分段错误,我不知道为什么。因为当我说出第一个名字时,一切都很好 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <stdbool.h> #define SIZE 30 /*The size

我必须写一个函数,它得到30个没有重复名称的名称,然后在这30个名称上随机打印。但当我在输入第二个名字后运行程序时,出现了分段错误,我不知道为什么。因为当我说出第一个名字时,一切都很好

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

#define SIZE 30  /*The size of the array of names*/
#define MAX_L 21    /*The length of a name included  the ending 0*/
#define REPEAT 10 /*The amount of getting a random name in the names list */

char names[SIZE][MAX_L];/* = { 0 } ; /*Global array for the names we get from the users*/

/*Gives back a random name in an array nameslist*/
char * get_name(){
    int random; /*the random index we get of the names list*/
    char *r; /*the string name to return*/

    random= rand()%SIZE; /*picks a random number from 0-29 */
    r= names[random]; /*r points to the random name in the list*/
    return r;
}


/*Gets from user 30 names without repeat and calls after that function get_names 10 times*/
int  main(){
    int i;  /*counter for array names list */
    int j;  /*counter for array in the first inner loop to check if there are repeated names*/
    int k;  /*counter for the repeat loop for random names*/
    int w;  /*counter for the index of the character in the string */
    bool same = true; /*says if two strings are the same or not*/

    for (i=0; i< SIZE; i++){  /*Gets from the user 30 names and initialize them in the array*/
        printf("\nPlease enter a name (repeated names forbidden until we'll get to 30 names)\n");
        scanf("%s", names[i]);

       if (i>0){
       for (j=0; j<i; j++){  /*checks if is a repeated name or not*/
        for (w=0; w< MAX_L || same ==false; w++){
            if (names[i][w] != names[j][w]){
                    if (names[i][w] >= 'a' && names[i][w] <= 'z'){ 
                            if (names[i][w] - 32 != names[j][w]) 
                                same=false;}

                else if (names[i][w] >= 'A' && names[i][w] <= 'Z'){
                            if (names[i][w] + 32 != names[j][w]) 
                                same=false;}
            }
        }   
        if (same ==true){ /*repeated name*/
             printf("\nERROR! You already entered this name!");
             return 0;}     
       }}
       printf("\nThe name you entered is: %s\n", names[i]);
    }

    for (k=0; k<REPEAT; k++){ /*Calls the function get_name 10 times to get 10 random names from the array*/
        printf("\nThe random name you got from the list is: %s", get_name());
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义大小30/*名称数组的大小*/
#定义MAX_L 21/*包含结尾0的名称的长度*/
#定义重复10/*在名称列表中获取随机名称的数量*/
字符名称[大小][最大值];/*={ 0 } ; /*从用户处获取的名称的全局数组*/
/*返回数组名称列表中的随机名称*/
char*get_name(){
int random;/*名称列表的随机索引*/
char*r;/*要返回的字符串名称*/
random=rand()%SIZE;/*从0-29中选择一个随机数*/
r=名称[随机];/*r指向列表中的随机名称*/
返回r;
}
/*从用户获取30个名称,不重复,并在该函数之后调用get_name 10次*/
int main(){
int i;/*数组名称列表的计数器*/
int j;/*第一个内部循环中数组的计数器,用于检查是否有重复的名称*/
int k;/*随机名称重复循环的计数器*/
int w;/*用于字符串中字符索引的计数器*/
bool same=true;/*表示两个字符串是否相同*/
for(i=0;i0){
对于(j=0;j='a'&&names[i][w]='a'&&names[i][w]用于调试程序

您需要做的只是:

  • 使用
    -g
    标志编译程序,例如:
    gcc-g-Wall main.c-o prog
  • 启动gdb:
    gdb prog
  • 设置断点(-s):
  • gdb)b 36
    断点
    
  • 运行您的程序:
    (gdb)r
  • 使用
    s
    逐步调试,使用
    c
    继续下一个断点
  • 您将很容易发现细分错误的原因:

    Program received signal SIGSEGV, Segmentation fault.
    0x000055555555526f in main () at main.c:39
    39                  if (names[i][w] != names[j][w]){
    
    要了解其确切原因,可以使用
    p%variable name%
    打印变量:

    (gdb) p i
    $1 = 1
    (gdb) p w
    $2 = 139115
    (gdb) p j
    $3 = 0
    (gdb) p same
    $4 = false
    

    所以原因很明显:
    same==false
    条件使您的
    w
    变量溢出。

    “我遇到分段错误,我不知道为什么”。尝试找出原因的方法是在调试器中运行程序。您在
    return r;
    处返回局部变量的地址与问题没有直接关系,但逐字符比较是比较字符串的一种低效方法。类似strcmp(toupper(names[i])、toupper(names[j])将两个名称转换为大写将消除正负32个大小写。
    w
    看起来非常危险。
    的要点是不要将
    same
    true
    false
    进行比较。只要使用
    if(same)
    if(!same)
    。输入等号太容易出错,造成通常很难找到的错误。谢谢你的回答!如果我想让代码更容易一点,请回答一个问题,比较没有布尔值的字符串和比较部分中的每个字符。我该如何做。我尝试了此代码,但没有成功。if(strlen(names[i])==strlen(names[j]){if(strcmp(toupper(names[i]),toupper(names[j])==0){printf(“\n错误!您已经输入了这个名称!”);返回0;}}
    if(strlen(names[i])==strlen(names[j]){if(strcmp(toupper(names[i]),toupper(names[j])==0){printf(“\n错误!您已经输入了这个名称!”);返回0;}
    更新后的代码有很多功能,
    toupper
    函数,它用于
    int
    变量,而不是字符串。顺便说一下,别忘了将我的答案标记为已接受‎✓ 签字,谢谢阿尔特姆·邦达