2

文字列を関数に渡し、その文字列に関するデータを含む構造体を返すという単純な目的を達成しようとしています。これを書いたのですが、コンパイルしようとすると実行時エラーが発生し、その理由がわかりません。ご覧いただきありがとうございます。

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

struct stringStats
{
    int length;
    int uppercase;
    int lowercase;
    int digits;
    int nonAlphaNum;
};

struct stringStats stringReader (char anyString[])
{
    int i;
    struct stringStats returned = {0, 0, 0, 0, 0 };

    returned.length = strlen(anyString);

    for (i = 0; anyString[i] != '\0'; ++i)
    {
        if (isupper(anyString[i]))
            ++returned.uppercase;
        if (islower(anyString[i]))
            ++returned.lowercase;
        if (isdigit(anyString[i]))
            ++returned.digits;
        if (isalnum(anyString[i]) == 0)
            ++returned.nonAlphaNum;
    }
    return returned;
}

int main(void)
{
    struct stringStats stored;
    char passedString[] = "Th1s string's g0t it all!";
    stored = stringReader(passedString);
    printf ("%i\n%i\n%i\n%i\n%i\n", stored.length, stored.uppercase, stored.lowercase,
                                    stored.digits, stored.nonAlphaNum);

return 0;
}
4

3 に答える 3

2

ここにいくつかの問題があります。

  1. main() にはchar passedString = "Th1s string's g0t it all!";- char は単一の文字を格納するため、これはchar *passedString = "Th1s string's g0t it all!";

  2. returnedメンバーをインクリメントする前に初期化していません。

  3. forループの終了条件はiそれ自体の値をチェックしていますが、実際anyString[i]にはnull文字で終了する値をチェックしたいのです。

于 2013-04-05T10:39:04.993 に答える
2

これは正しくありません:

char passedString = "Th1s string's g0t it all!";

これがどのようにコンパイルされたのかわかりません (最高の警告レベルでコンパイルし、警告をエラーとして扱うことをお勧めします):

$ gcc -O2 -Wall -Werror -std=c99 -pedantic main.c -o main -pthread
main.c: 関数 'main' 内:
main.c:38:25: エラー: 初期化により、キャストなしでポインターから整数が作成されます [-Werror]
main.c:39:5: エラー: 'stringReader' の引数 1 を渡すと、キャストなしで整数からポインターが作成されます [-Werror]
main.c:14:20: 注: 'char *' が必要ですが、引数の型は 'char' です
cc1: すべての警告がエラーとして扱われます

タイプはchar[]次のとおりです。

char passedString[] = "Th1s string's g0t it all!";

ローカル変数のアドレスではなく、ローカル変数のコピーが (値によって) 返されるため、戻り値の型は正当であることに注意してください。2 つの s が同じアドレスを指すメンバーを持っているため、にポインター メンバーが含まれているstruct場合、 a のコピーは危険であることに注意してください (ダングリング ポインターの潜在的な原因)。structstruct

ただし、ローカルstructは現在は初期化されていないため、初期化する必要があります。

struct stringStats returned = {0}; /* All members initialized to zero. */

forループ条件が正しくないため、ループの本体が実行されません (最初の評価はfalse0 != '\0'になります)。への変更:

for (i = 0; anyString[i]; ++i)
{
}
于 2013-04-05T10:33:37.223 に答える
0

ローカル構造体の値を呼び出し元のオブジェクトに返しています。私の経験から、参照を渡すだけで内部で操作を実行する方が安全です。

これを見てください::

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

struct stringStats
{
    int length;
    int uppercase;
    int lowercase;
    int digits;
    int nonAlphaNum;
};

int stringReader (char anyString[], struct stringStats *returned)
{
    int i;
    returned->digits=0;
    returned->length=0;
    returned->lowercase=0;
    returned->nonAlphaNum=0;
    returned->uppercase=0;

    returned->length = strlen(anyString);

    for (i = 0; anyString[i] != '\0'; ++i)
    {
        if (isupper(anyString[i]))
            ++returned->uppercase;
        if (islower(anyString[i]))
            ++returned->lowercase;
        if (isdigit(anyString[i]))
            ++returned->digits;
        if (isalnum(anyString[i]) == 0)
            ++returned->nonAlphaNum;
    }
    return 0;
}

int main(void)
{
    struct stringStats stored;
    char passedString[] = "Th1s string's g0t it all!";
    stringReader(passedString,&stored);
    printf ("%i\n%i\n%i\n%i\n%i\n", stored.length, stored.uppercase, stored.lowercase,
                                    stored.digits, stored.nonAlphaNum);

    return 0;
}

これは私の側で完全にコンパイルおよび実行されます。お役に立てれば!

于 2013-04-05T11:45:59.623 に答える