由 C 中的 fgets() 引起的分段错误


这是一个

我不明白的问题 - 我在main中使用fgets()并且它可以工作。 我在函数中以完全相同的方式使用它(我认为),并且出现错误 [分段故障核心转储 - 退出代码 139)。

这段代码基于 Ivor Horton 的"Beginning C"一书中的示例程序(这是一个古老的磁贴,但我只是想从中学习基础知识)。

我的程序如下。 我正在使用 Geany 处理 *nix(基本上是使用 GCC 编译)。 您可以看到fgets在 main 中工作(输出是您输入的字符串)。 但它在函数str_in()中不起作用。 它最远到达第二个printf()语句以输入字符串,仅此而已。 请注意,在书中,霍顿使用了gets() . 我正在尝试在这里实现一个更安全的字符串输入函数,但没有乐趣。

顺便说一下,程序应该对存储在字符串指针数组中的字符串进行排序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAX_NUM_STRINGS 50

int str_in(char **);              /*Pointer to a string pointer*/
void str_sort(char *[], int n);   /*Array of pointers to strings, number of strings in array*/
void str_out (char *[], int n);   /*Array of pointers to strings, number of strings in array*/

int main(){
    char *pS[MAX_NUM_STRINGS] = { NULL };                  /*Array of pointers to strings stored in str_space*/
    int numStrings = 0;                                     /*Count of strings*/
    char buffer[BUFSIZ];
    printf("Enter a stringn");
    fgets(buffer, BUFSIZ, stdin);
    printf("%s", buffer);
    printf("fgets works herenn");

    /* get string input from user - a pointer to each string is saved in pS */
    while ( str_in(&pS[numStrings]) && numStrings < MAX_NUM_STRINGS)
        numStrings++;
    if ( numStrings > 0 ){
        str_sort(pS, numStrings);
        str_out(pS, numStrings);
    }
    return 0;
}

    int str_in(char** pString){
        char buffer[BUFSIZ];
        char *p;
        printf ("Enter string:n");
        fgets(buffer, 60, stdin);
        printf("fgets doesn't work here!!n");
        if( buffer != NULL ){
            printf("here");
            if ((p = strchr(buffer, 'n')) != NULL)
                *p = '';                                  /*replace newline with null character*/
            else
                return FALSE;
            if ( strlen(buffer) > 0 ){
                strcpy(*pString, buffer);
                return TRUE;
            }
            else
                return FALSE;                               /*blank line - end of input*/
        }
        else
            return FALSE;
    }

    void str_sort(char* pStrings[], int n){
    /*sort strings by manipulating array of string pointers*/
        char *temp;
        int sorted = FALSE;
        int i = 0;
        while (!sorted){
            sorted = TRUE;
            for(i = 0; i < n - 1; i++){
                temp = pStrings[i];
                if ( strcmp(temp, pStrings[i+1]) > 1 ){
                    pStrings[i] = pStrings[i+1];
                    pStrings[i+1] = temp;
                    sorted = FALSE;
                    break;
                }
            }
        }
    }

    void str_out(char* pStrings[], int n){
    /*print strings to standard output.  Free memory as each string is printed */
        int i = 0;
        printf("Sorted strings:n");
        for(i = 0; i < n; i++){
            printf("%s", pStrings[i]);
            free(pStrings[i]);
        }
    }

分割错误不是由fgets()引起的,而是由strcpy()引起的:

strcpy(*pString, buffer);

你尝试写入*pString,但从不为其分配内存。 pS main() 只是一个空指针数组。

另一件事是用if( buffer != NULL )进行测试,这永远不会是真的,因为buffer是一个数组,而不是一个指针。

您必须检查 fgets 的返回值以查看您是否成功接收了某些内容,如果没有,则永远不要将缓冲区用作字符串,因为您没有 NUL 终止缓冲区。

/* Checking for buffer != NULL is of no use */
/* as buffer will always be not NULL since */
/* since you have allocated it as char buffer[BUFSIZ] */
if (fgets(buffer, BUFSIZ, stdin) == NULL) {
   /* buffer may not be a valid string */
}

那么,一旦您输入函数(在声明完成后),您就可以将缓冲区初始化为 NUL 字符串

buffer[0] = 0; /* initialize to NUL string */

现在,您可以在任何地方将缓冲区用作字符串。

另请注意,如果 BUFSIZ 太大大于几 KB,那么您可能会由于堆栈溢出而出现 seg 错误。如果它们太大,您可以将缓冲区设置为"静态字符"而不是"字符"。

相关内容

  • 没有找到相关文章

最新更新