[英]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.