1

所以这是我在 C 语言中的第三周,我的任务是编写一个程序,该程序最多可以接收 100 个单词,最长 80 个字符,计算输入的平均单词长度,打印大于平均值的单词,并且最后打印平均字长。 编辑:我们还必须使用 emalloc,一种递归输出方法,并释放所有使用的内存。

成功!……至少我是这么想的。

我在 Eclipse 中编写了以下内容,gcc -E -P -v -dD用作其编译参数,并且在使用提供的测试用例运行程序时,我没有遇到运行时错误。

现在我已经完成了我必须在 30 分钟的实际操作中重现它的代码。我们被告知必须使用文本编辑器,并且gcc -W -Wall -ansi -pedantic必须将其用作编译参数,但如果我使用这些参数,则意味着我的程序总是以“总线错误”退出

编辑:固定和格式化

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

#define MAXIMUM_STRING_LENGTH 80
#define MAXIMUM_ARRAY_LENGTH 100

void* memory_allocation(size_t sizeof_memory_required) {

    void* free_memory_pointer = malloc(sizeof_memory_required);

    if (free_memory_pointer/*exists*/) {
        return free_memory_pointer;
    } else {
        fprintf(stderr, "*** MEMORY ALLOCATION FAILURE ***\n");
        exit(EXIT_FAILURE);
    }
}

void print_larger_than_average_strings(char** string_pointers, int i, const double AVERAGE_STRING_LENGTH) {

    if (string_pointers[i]/*exist*/) {
        if (strlen(string_pointers[i]) > AVERAGE_STRING_LENGTH) {
            printf("%s\n", string_pointers[i]);
        }
        print_larger_than_average_strings(string_pointers, ++i, AVERAGE_STRING_LENGTH);
    } else {
        fprintf(stderr, "%.2f\n", AVERAGE_STRING_LENGTH);
    }
}

int main(void) {

    int string_count = 0;
    char string[MAXIMUM_STRING_LENGTH];
    char* string_pointer[MAXIMUM_ARRAY_LENGTH];
    int i;
    double character_count;

    while ((string_count < MAXIMUM_ARRAY_LENGTH) && (1 == scanf("%79s", string))) {
        string_pointer[string_count] = memory_allocation(sizeof string_pointer[0][0] * (strlen(string) + 1));
        strcpy(string_pointer[string_count++], string);
    }
    string_pointer[string_count] = NULL;
    for (i = 0; i < string_count; i++) {
        character_count += strlen(string_pointer[i]);
    }
    if (string_count/*exists*/) {
        print_larger_than_average_strings(string_pointer, 0, character_count / string_count);
        for (i = 0; i < string_count; i++) {
            free(string_pointer[i]);
        }
    }
    return EXIT_SUCCESS;
}
4

3 回答 3

3

递归函数的终止条件o被破坏。字符串数组不是以 null 结尾的,为什么会这样呢?为什么不在那里使用简单for函数,而不是递归函数?就像是:

for(i=0;i<wc;i++) {
      if(strlen(wpp[i])>av)
         printf("%s\n",wpp[i]); 
 }

这是我发现的方法,使用gdb

t@c:~/tmp$ gcc -g -Wall -W -ansi -pedantic test.c                      
t@c:~/tmp$ gdb ./a.out
GNU gdb 6.8-debian                  
版权所有 (C) 2008 Free Software Foundation, Inc.
许可 GPLv3+:GNU GPL 版本 3 或更高版本
这是免费软件:您可以自由更改和重新分发它。           
在法律允许的范围内,不提供任何保证。输入“显示复制”
和“显示保修”了解详情。
此 GDB 配置为“i486-linux-gnu”...
(gdb) r
启动程序:/home/tudor/tmp/a.out
sdafasd
萨萨
咻咻咻咻
啊啊啊啊
屁股
咻咻咻咻
啊啊啊啊

程序收到信号 SIGSEGV,分段错误。
/lib/i686/cmov/libc.so.6 中的 strlen () 中的 0xb7eba1e3
(gdb) BT
#0 0xb7eba1e3 in strlen () from /lib/i686/cmov/libc.so.6
#1 0x08048618 in o (wpp=0xbffad51c, av=7.5999999999999996, i=5) at test.c:13
#2 0x08048662 in o (wpp=0xbffad51c, av=7.5999999999999996, i=5) at test.c:14
#3 0x08048662 in o (wpp=0xbffad51c, av=7.5999999999999996, i=4) at test.c:14
#4 0x08048662 in o (wpp=0xbffad51c, av=7.5999999999999996, i=3) at test.c:14
#5 0x08048662 in o (wpp=0xbffad51c, av=7.5999999999999996, i=2) at test.c:14
#6 0x08048662 in o (wpp=0xbffad51c, av=7.5999999999999996, i=1) at test.c:14
#7 0x0804876c in main () at test.c:25
(gdb) 帧 1
#1 0x08048618 in o (wpp=0xbffad51c, av=7.5999999999999996, i=5) at test.c:13
13 if(strlen(wpp[i])>av)printf("%s\n",wpp[i]);
(gdb) 圆周率
$1 = 5
(gdb) p wpp
$2 = (char **) 0xbffad51c
(gdb) p *wpp[i]
无法访问地址 0x8 处的内存
于 2009-08-03T11:16:50.710 回答
3

您在递归函数“o”中有错误的“停止条件”。它检查 if(wpp[i]) 但该数组的最后一个元素未初始化为 NULL。您应该:将“char *wp[100]”更改为“char *wp[101]; wp[100]=NULL;”。然后它应该可以工作,但它仍然不是一段漂亮的代码..

于 2009-08-03T11:18:03.467 回答
1

递归函数中没有终止条件,名为o. 你必须以某种方式停止递归。

试试这个不递归的代码:

void* AllocateMemory(size_t s)
{
    void* mp = malloc(s);
    if(mp)
        return mp;
    else 
    {
        fprintf(stderr,"MALLOC FAILED!\n");
        exit(1);
    }
}

void PrintLargerWords(const char* wpp, double av)
{
    if(wpp)
    {
        if(strlen(wpp) > av)
            printf("%s\n",wpp);
    }
    else 
        fprintf(stderr,"%.2f\n",av);
}

int main(void)
{
    char w[80];
    char* wp[100];
    int wc=0;
    double cc=0;
    while(wc<5 && 1==scanf("%79s",w))
    {
        int length = strlen(w);
        wp[wc]= (char*)AllocateMemory((length+1) * sizeof(wp[0][0]));
        strcpy(wp[wc++],w);
        cc += length;
    }
    for(int j = 0; j<wc; j++)
    {
        PrintLargerWords(wp[j],cc/wc);
    }
    for(int i=0; i<wc; i++)
        free(wp[i]);
    return 0;
}

我还没有碰过你的大部分代码。也要进行适当的错误检查。

于 2009-08-03T11:15:48.450 回答