繁体   English   中英

最长字符串数组分段错误

[英]longest string array segmentation fault

编写一个C函数longestStrInAr() ,它接受一个字符串数组strsize (>0)作为参数,并通过指针参数length返回最长字符串和最长字符串的长度。 如果两个或多个字符串的最长字符串长度相同,则将第一个出现的字符串返回给调用函数。 例如,如果size5并且字符串数组是{ "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
之后,这个lengthNULL )被取消引用,它会导致分段错误。

要将参数length指向的内容初始化为零,该行应为:

int j = 0, max = 0; *length = 0;

在函数longestStrInAr中, for循环中的代码不正确:

    int j = 0; int max = 0, *length = 0;

定义 3 个局部变量: jmaxlength作为指向int的新指针,初始化为空指针。 length变量与函数参数具有相同的名称,但定义在作为for语句主体的块的范围内,因此它会隐藏具有相同名称的参数。 如果给出更高级别的警告( gcc -Wall -Wextra -Wshadowclang -Weverything ),编译器会诊断出这个问题。

这导致了分段错误:当您稍后在if (max > *length)中取消引用此指针时,您有未定义的行为,因为length是一个空指针。

您可能只想使用参数并初始化*length ,您应该在for循环之前执行此操作。 另请注意,您应该将p初始化为p = str[0]对于所有字符串为空且发布的代码返回未初始化指针的病态情况。 事实上,还有另一种特殊情况需要考虑:如果size0 ,函数应该返回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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM