C 带字符串的分段错误(堆芯转储)
我必须写一个函数,它得到30个没有重复名称的名称,然后在这30个名称上随机打印。但当我在输入第二个名字后运行程序时,出现了分段错误,我不知道为什么。因为当我说出第一个名字时,一切都很好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
#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
变量,而不是字符串。顺便说一下,别忘了将我的答案标记为已接受✓ 签字,谢谢阿尔特姆·邦达