1

C での私の人生の 3 週目で、最大 80 文字の長さの最大 100 語を取り込み、入力の平均語長を計算し、平均より大きい語を出力し、最後に、平均単語サイズを出力します。 編集: また、再帰的な出力方法である 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                  
Copyright (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) ところで
#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 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 = (文字 **) 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 に答える