You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字符指针数组排序程序无法正确读取输入单词问题排查

解决字符指针数组排序时的垃圾字符问题

我想实现一个程序,对元素为char指针的数组中的单词列表进行排序并展示。我用malloc为每个元素分配内存,通过read_line函数把输入的单词存到元素里,但问题是每个单词都包含随机垃圾字符,好像程序没正确读取并存储我输入的字符。我试过用strcpy、strcat,还调整过读取和内存分配代码的顺序,都没解决问题。以下是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX 100
#define LEN 20

int string_compare(const void *n, const void *m);
int read_line(char *str, int n);

int main(void)
{
    int i, num_words, largo;
    char *list[MAX], word[LEN+1];

    for (i=num_words=0; i<MAX; i++, num_words++) {
        printf("Enter word: ");
        list[i] =  malloc(LEN + 1);

        if (list[i] == NULL) {
            printf("Error, no more memory available\n");
            break;
        }

        largo = read_line(word, LEN) ;      // 不知道为什么函数读取的字符串是随机字符(垃圾值)
        if (largo == 0)                     // 
            break;       // break已经生效  

        printf("Copying string %s...\n",list[i]);
        strcpy(list[i], word);
    }

    qsort(list, i, 21 * sizeof(char), string_compare);
    

    printf("In sorted order: ");
    for (i=0; i < num_words; i++) 
        printf("Displaying...\n");
        printf("%s ", list[i]);
    
    return 0;
}

int string_compare(const void *n, const void *m)
{
    return strcmp((char *) n, (char *) m);
}

int read_line(char *str, int n)
{
    int ch, i=0;

    while ((ch=getchar()) != '\n')
        if (i < n)
            str[i++] = ch;
    str[i] = '\0';
    
    return i;
}

代码中的关键错误

  • 未初始化内存提前打印:在strcpy(list[i], word);之前就执行printf("Copying string %s...\n",list[i]);,此时list[i]是刚malloc的未初始化内存,里面全是随机垃圾字符,这会让你误以为是read_line读取错误,但实际上是打印时机错误。
  • qsort参数错误:qsort的第三个参数是数组中每个元素的字节大小,list是char*类型的数组,每个元素是指针,应该传sizeof(char*)而非21 * sizeof(char)。错误参数会导致qsort排序时错误操作内存,破坏数据。
  • 循环缩进错误:输出排序结果的for循环中,只有printf("Displaying...\n");在循环体内,printf("%s ", list[i]);在循环体外。这会导致只打印一次提示,然后访问越界的list[num_words],输出垃圾值。
  • string_compare类型转换错误:qsort传入的参数是数组元素的指针(即char**),直接转成char*传给strcmp,会让strcmp比较指针地址而非字符串内容。
  • read_line函数缺陷:未处理输入缓冲区残留字符(输入超长时,多余字符会留在缓冲区干扰后续读取),也未处理EOF(用户按Ctrl+D/Ctrl+Z),会导致死循环。

修正后的代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX 100
#define LEN 20

int string_compare(const void *n, const void *m);
int read_line(char *str, int n);

int main(void)
{
    int i, num_words, largo;
    char *list[MAX], word[LEN+1];

    for (i=num_words=0; i<MAX; i++) {
        printf("Enter word: ");
        list[i] = malloc(LEN + 1);

        if (list[i] == NULL) {
            printf("Error, no more memory available\n");
            break;
        }

        largo = read_line(word, LEN);
        if (largo == 0) {
            free(list[i]);  // 空输入时释放内存,避免泄漏
            break;
        }

        strcpy(list[i], word);
        num_words++;  // 仅成功读取单词时计数
    }

    // 修正qsort参数:每个元素是char*,大小为sizeof(char*)
    qsort(list, num_words, sizeof(char*), string_compare);

    printf("In sorted order: ");
    for (i=0; i < num_words; i++) {
        printf("%s ", list[i]);
        free(list[i]);  // 释放内存,避免泄漏
    }
    printf("\n");
    
    return 0;
}

// 修正类型转换:n和m是char**,解引用后得到字符串指针char*
int string_compare(const void *n, const void *m)
{
    return strcmp(*(char **)n, *(char **)m);
}

int read_line(char *str, int n)
{
    int ch, i=0;

    // 跳过开头空白字符(可选,不需要可删除)
    while ((ch = getchar()) != EOF && isspace(ch) && ch != '\n');
    if (ch == EOF || ch == '\n') {
        str[0] = '\0';
        return 0;
    }
    str[i++] = ch;

    while ((ch = getchar()) != EOF && ch != '\n') {
        if (i < n) {
            str[i++] = ch;
        }
    }
    str[i] = '\0';

    // 清空缓冲区中超过长度限制的残留字符
    if (ch != EOF && ch != '\n') {
        while ((ch = getchar()) != EOF && ch != '\n');
    }
    
    return i;
}

修正说明

  1. 调整计数逻辑:把num_words++移到循环体内,仅成功读取单词后计数;空输入时释放刚分配的内存,避免内存泄漏。
  2. 修复qsort参数:确保传入正确的元素大小,让qsort正确处理指针数组。
  3. 修正循环缩进:给输出循环加上大括号,确保所有输出语句都在循环体内。
  4. 修复字符串比较函数:正确解引用qsort传入的指针参数,让strcmp比较字符串内容而非地址。
  5. 完善read_line函数:处理EOF情况、清空残留缓冲区字符,避免后续输入被干扰;可选跳过开头空白字符。

内容的提问来源于stack exchange,提问作者Pepe Cuesta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:50:09