1

ここでの初心者の皆さん、私は宿題を与えられました。そこでは、geditを使用して、コマンドラインからファイル名を読み込むプログラムを設計し、getNextWordメソッドを設計します。英数字以外のすべてを無視して(大文字を小文字に変換して)、各ファイルを一度に1つずつ開き、単語を返すだけです。私がハングアップしているのは、インストラクターが私たちを助けるためにstrdup()関数を与えてくれただけでなく、isspace、alnumなどです。とにかく、このサイトでstrdup()を調べた後、Cの基本とサイトなど私が理解していないことがあるに違いありません。私のプログラムはコンパイルされ(gcc -Wall -pedantic -std = c99 words.c -o wordsを使用します)、strdup()が暗黙的に使用されているという警告だけでコンパイルされます。同じディレクトリにいくつかのテキストファイルを含むプログラムを実行すると、ヒープの境界を超えて実行されているかのようにゴブリーグックが出力され、セグメンテーション違反(コアダンプ)が発生します。ポインタのstrdupを返す前に文字配列の最後に\0を置くなど、適切なチェックも行っていると思いました。これが私のコードです。誰かが私のハードウェアをやってくれるとは思っていません。一日中調べて問題を見つけることができないので、観察が役立つかもしれません。これを読んでくれてありがとう(表示されていませんが、stdio、stdlib.h、string.h、ctype.hを含めました 私は一日中調査していて問題を見つけることができないので、観察が役立つかもしれません。これを読んでくれてありがとう(表示されていませんが、stdio、stdlib.h、string.h、ctype.hを含めました 私は一日中調査していて問題を見つけることができないので、観察が役立つかもしれません。これを読んでくれてありがとう(表示されていませんが、stdio、stdlib.h、string.h、ctype.hを含めました

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_WORD_SIZE 256


char* getNextWord(FILE* fd)
{

    int index = 0;
    int c;

    char str[MAX_WORD_SIZE];

    while((c = fgetc(fd)) != EOF){

        c = fgetc(fd);

        if (isspace(c)){
            str[index] = '\0';
            return (char*) strdup(str);
        }

        if (((index+1) != (MAX_WORD_SIZE-1)) && (isalnum(c))){
            c = tolower(c);
            str[index] = c;
            index++;
        }
        else {
            index++;
            str[index] = '\0';
            return (char*) strdup(str);
        }

    }

    return NULL;
}

int main(int argc, char* argv[])
{
    char** current = argv;
    char* heapedString = NULL;

    while (*current)
    {
        char* filename = *current;
        FILE* fd = fopen(filename, "r");
        if (fd == NULL)
        {
            fprintf(stderr,"can't read the file\n");
            exit(-1);
        }

        while ((heapedString = getNextWord(fd)) != NULL)
        {
            heapedString = getNextWord(fd);
            printf("%s\n", heapedString);
            free(heapedString);         
        }   
        fclose(fd);
        current++;  

    }
    return 0;
}
4

5 に答える 5

4

おそらく、他のすべての文字と単語を破棄しているためです。両方の while で同じ種類のエラーが発生します。

while((c = fgetc(fd)) != EOF){

    c = fgetc(fd);

    ....
}

ループごとに 1 回だけ fgetc (または getNextWord) を呼び出す必要があります。次のいずれかを行う必要があります。

while((c = fgetc(fd)) != EOF){
    ....
}

またはこれ:

while(1){
    c = fgetc(fd);
    if (c == EOF) break;
    ....
}

しかし、両方の組み合わせではありません

于 2013-01-20T03:27:42.073 に答える
3

憶測ですが、以下の2行がエラーの原因だと思います。

while((c = fgetc(fd)) != EOF){
c = fgetc(fd);

内部ファイル位置インジケータは、使用するたびに次の文字に進みます。そのため、while ループの呼び出しで進められます。これはおそらくあなたの望む結果を台無しにしています。

ここにあるコードを見て、代わりに do while が使用されていることに注意してください。幸運を!
http://www.cplusplus.com/reference/cstdio/fgetc/

于 2013-01-20T03:27:51.997 に答える
1

strdup質問の一部の暗黙の宣言に関してはstrdup、他の多くの一般的に使用される関数と同様に、C99標準ライブラリの一部ではありません。「glibcの機能テストマクロ要件」の部分を見て確認すると、ライブラリを含める前にman strdup何をする必要があるかがわかります。#define例えば:

#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *foo = "foo";
    char *bar = strdup(foo);
    puts(bar);
    free(bar);
}

POSIX機能を使用し、同時に-std = c99オプションを使用して、可能な限りISO C99に準拠したい場合は、これに遭遇します。

于 2013-01-20T09:16:44.703 に答える
1

各反復で fgetc を 2 回呼び出しています。getNextWord を呼び出すときにも同じ間違いを犯します。

于 2013-01-20T03:25:42.453 に答える
0

マイナーな問題ですが、なぜ使用しているのですか

if (((index+1) != (MAX_WORD_SIZE-1)) && (isalnum(c)))

あなたの小切手として?インデックスから +1 を削除するだけで十分だと思います。私が使用しているこの割り当てのコードについて

if ( isalnum( c ) && ( j <= ( MAX_WORD_SIZE - 1 ) ) )

そして、割り当てAFAICTで必要とされるとおりに正確に機能します(明らかに、「インデックス」としてjがあり、順序は関係ありません)

main にチェックを追加して、heapedString[0] == '\0' も確認する必要があります。そうしないと、多くの空の行が出力されます。これでも割り当ては満たされるかもしれませんが、出力しない方がよいでしょう。

于 2013-01-22T03:34:27.523 に答える