[英]longest string array segmentation fault
编写一个C函数longestStrInAr()
,它接受一个字符串数组str
和size
(>0)作为参数,并通过指针参数length返回最长字符串和最长字符串的长度。 如果两个或多个字符串的最长字符串长度相同,则将第一个出现的字符串返回给调用函数。 例如,如果size
为5
并且字符串数组是{ "peter", "john", "mary", "jane", "kenny"}
,那么最长的字符串是"peter"
并且字符串长度是5
将返回到调用函数
我在这里遇到分段错误,我不知道为什么。
#include <stdio.h>
#include <string.h>
#define N 20
char *longestStrInAr(char str[N][40], int size, int *length);
int main() {
int i, size, length;
char str[N][40], first[40], last[40], *p, *result;
char dummychar;
printf("Enter array size: \n");
scanf("%d", &size);
scanf("%c", &dummychar);
for (i = 0; i < size; i++) {
printf("Enter string %d: \n", i + 1);
fgets(str[i], 40, stdin);
if (p = strchr(str[i], '\n'))
*p = '\0';
}
result = longestStrInAr(str, size, &length);
printf("longest: %s \nlength: %d\n", result, length);
return 0;
}
char *longestStrInAr(char str[N][40], int size, int *length) {
char *p;
for (int i = 0; i < size; i++) {
int j = 0; int max = 0, *length = 0;
while (str[i][j++] != '\0') {
max++;
}
if (max > *length) {
*length = max;
p = str[i];
}
}
return p;
}
线
int j = 0; int max = 0, *length = 0;
不好。 此处声明了一个新的指针变量length
并将其初始化为NULL
,从而隐藏参数length
。
之后,这个length
( NULL
)被取消引用,它会导致分段错误。
要将参数length
指向的内容初始化为零,该行应为:
int j = 0, max = 0; *length = 0;
在函数longestStrInAr
中, for
循环中的代码不正确:
int j = 0; int max = 0, *length = 0;
定义 3 个局部变量: j
、 max
和length
作为指向int
的新指针,初始化为空指针。 此length
变量与函数参数具有相同的名称,但定义在作为for
语句主体的块的范围内,因此它会隐藏具有相同名称的参数。 如果给出更高级别的警告( gcc -Wall -Wextra -Wshadow , clang -Weverything ),编译器会诊断出这个问题。
这导致了分段错误:当您稍后在if (max > *length)
中取消引用此指针时,您有未定义的行为,因为length
是一个空指针。
您可能只想使用参数并初始化*length
,您应该在for
循环之前执行此操作。 另请注意,您应该将p
初始化为p = str[0]
对于所有字符串为空且发布的代码返回未初始化指针的病态情况。 事实上,还有另一种特殊情况需要考虑:如果size
为0
,函数应该返回NULL
。
main
函数中也存在一些问题:如果size
大于N
,您会读取超出数组末尾的字符串。
这是修改后的版本:
#include <stdio.h>
#define N 20
char *longestStrInAr(char str[][40], int size, int *length);
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
int i, size, length;
char str[N][40];
char *result;
printf("Enter array size: \n");
if (scanf("%d", &size) != 1 || size < 0 || size > N) {
fprintf(stderr, "invalid input\n");
return 1;
}
// read and discard the rest of the input line
flush_input();
for (i = 0; i < size; i++) {
printf("Enter string %d: \n", i + 1);
str[i][0] = '\0';
scanf("%39[^\n]", str[i]);
flush_input();
}
result = longestStrInAr(str, size, &length);
printf("longest: %s \nlength: %d\n",
result ? result : "(null)", length);
return 0;
}
char *longestStrInAr(char str[][40], int size, int *length) {
char *p = NULL;
*length = 0;
if (size > 0) {
for (int i = 0; i < size; i++) {
int j = 0;
while (str[i][j] != '\0')
j++;
if (*length < j) {
*length = j;
p = str[i];
}
}
}
return p;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.