C程序需要帮助修复单词排序程序的代码

时间:2015-05-13 19:18:11

标签: c arrays sorting

嗨,我仍然是c的新手,并且已经有一段时间在这个单词排序程序上工作了。准则是:

编写一个程序,对用户输入的一系列单词进行排序。假设每个单词长度不超过20个字符。当用户输入空字时停止阅读。使用指针数组将每个单词存储在动态分配的字符串中(使用read_line函数)。读完所有行后对数组进行排序。然后使用循环以排序顺序打印单词。

我似乎遇到的问题是程序会接受单词,但是当我输入空单词时,它会转到一个新行并且没有任何反应。非常感谢帮助或建议。到目前为止,这是我的代码。

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


#define LEN 20
#define LIM 20

int read_line(char str[], int n);
void sort_str(char *list[], int n);
int alpha_first(char *list[], int min_sub, int max_sub);


int main(void)
{
    char *list[LIM];
    char *alpha[LIM];
    char word_str[LEN];
    int word, i, j,  num_count = 0;

    for(;;){

        printf("Enter a word: ");
        scanf("%s", &word);
        if(word == NULL)
            break;
        else
            read_line(word_str, LEN);
            list[i] = malloc(strlen(word_str) + 1);
            strcpy(list[i], word_str);
            alpha[i] = list[i];     
    }


    sort_str(alpha, i);

        for(i = 0; i < num_count; ++i){
        printf("Sorted: ");
        puts(list[i]);
    }   

    return (0);
}

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;
}

void sort_str(char *list[], int n)
{

    int   i, index_of_min; 
    char *temp;

    for  (i= 0;  i < n - 1;  ++i) {
        index_of_min = alpha_first(list, i, n - 1);

        if (index_of_min != i) {
            temp = list[index_of_min];
            list[index_of_min] = list[i];
            list[i] = temp;
        }
    }
}


int alpha_first(char *list[], int min_sub, int max_sub){
    int i, first;

    first = min_sub;
    for(i = min_sub + 1; i <= max_sub; ++i){
        if(strcmp(list[i], list[first]) < 0){
           first = i;
        }
   }
return (first);
}

2 个答案:

答案 0 :(得分:1)

你的逻辑流程是有缺陷的。如果输入一个单词,scanf()将从stdin中获取它,并在整数'word'的地址处存储一个以空字符结尾的字符串。输入的任何超过3/7个字符(32/64位,允许空终止符)将开始破坏堆栈。 read_line()将只有行结束符从stdin读取(假设UB不会先将它炸掉)。

答案 1 :(得分:0)

  

我似乎遇到的问题是程序会接受单词,但是当我输入空单词时,它会转到一个新行并且没有任何反应。

这有几个问题:

char word_str[LEN];
int word, i, j,  num_count = 0;

/* ... */

    scanf("%s", &word);
    if(word == NULL)
        break;

首先,scanf("%s", &word)扫描以空格分隔的字符串,为此它跳过前导空格,包括换行符。你不能读一个空单词&#34;这样,如果在扫描任何非空格字符之前,如果到达输入的末尾(或发生I / O错误),则根本无法读取单词。

其次,您正在向scanf()传递不恰当的指针。 应该传递一个指向字符数组的指针,但是你会将指针传递给int。看起来您可能希望扫描到word_str而不是word

第三,您的scanf()格式无法防止缓冲区溢出。您应提供字段宽度以限制可扫描的字符数。此外,您需要确保为字符串终止符留出空间。

第四,您不检查scanf()的返回值。如果它无法匹配任何字符到字段,那么它将不存储任何字符。由于它返回成功扫描的字段数(或错误指示符),因此您可以检测到这种情况。

纠正scanf()和&#34;空字的一种方法&#34;测试将是:

int result;

result = scanf("%*[ \t]%19[^ \t\n]", word_str);
if (result < 1) break;

(假定最大字长为19,与声明的数组长度为20一致。)在较大的代码中有几个额外的问题,read_line()尝试读取相同的数据只是通过scanf()阅读(事实上,该功能看起来完全没有意义)。此外,您永远不会更新num_count,并且在致电sort_str()后,您会通过为变量i分配新值来忘记已读取的字符串数量。

也可能存在其他问题。