web-dev-qa-db-ja.com

ポインターを使用してchar配列を反復処理します

私はCで非常に新しく、ポインターを使用して配列の各要素を取得する方法について疑問に思っていました。配列のサイズがわかっている場合にのみ、これは簡単です。コードを次のようにします。

#include <stdio.h>

int main (int argc, string argv[]) {
    char * text = "John Does Nothing";
    char text2[] = "John Does Nothing";

    int s_text = sizeof(text); // returns size of pointer. 8 in 64-bit machine
    int s_text2 = sizeof(text2); //returns 18. the seeked size.

    printf("first string: %s, size: %d\n second string: %s, size: %d\n", text, s_text, text2, s_text2);

    return 0;
}

次に、textのサイズを決定します。これを行うには、文字列が'\0'文字で終わることがわかりました。そこで、次の関数を作成しました。

int getSize (char * s) {
    char * t; // first copy the pointer to not change the original
    int size = 0;

    for (t = s; s != '\0'; t++) {
        size++;
    }

    return size;
}

ただし、ループは終了しないため、この関数は機能しません。

だから、ポインタが指すcharsの実際のサイズを取得する方法はありますか?

ポインターをチェックする代わりに、現在の値をチェックする必要があります。次のようにできます:

int getSize (char * s) {
    char * t; // first copy the pointer to not change the original
    int size = 0;

    for (t = s; *t != '\0'; t++) {
        size++;
    }

    return size;
}

またはより簡潔に:

int getSize (char * s) {
    char * t;    
    for (t = s; *t != '\0'; t++)
        ;
    return t - s;
}
7
mdatsev

このforループにはタイプミスがあります

for (t = s; s != '\0'; t++) {
            ^^^^^^^^^          

私はあなたが意味すると思います

for (t = s; *t != '\0'; t++) {
            ^^^^^^^^^          

それにもかかわらず、一般に、関数は、終端のゼロもカウントする場合でも、演算子sizeofによって返される値と同等の値を提供しません。代わりに、標準関数strlenによって返される値と同等の値を提供します。

たとえば、このコードスニペットの出力を比較します

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

//...

char s[100] = "Hello christopher westburry";

printf( "sizeof( s ) = %zu\n", sizeof( s ) );
printf( "strlen( s ) = %zu\n", strlen( s ) + 1 );

したがって、関数は文字列の長さを計算するだけです。

次のように定義すると、より正確になります(ポインターを使用)

size_t getSize ( const char * s ) 
{
    size_t size = 0;

    while ( *s++ ) ++size;

    return size;
}
2