1

指定された文字列内の指定された文字のすべての位置を含む割り当てられたメモリブロックを埋め、メモリブロックへのポインタを返す小さな関数を作成しました。

この関数の唯一の問題は、メモリブロックのサイズをチェックする方法がないことです。そこで、文字列内の特定の文字の出現をカウントする関数も作成しました。

使用例を次に示します。

/*count occurences of char within a given string*/
size_t strchroc(const char *str, const char ch)
{ 
    int c = 0;
    while(*str) if(*(str++) == ch) c++;
    return c;
}

/*build array of positions of given char occurences within a given string*/
int *chrpos(const char *str, const char ch)
{
    int *array, *tmp, c = 0, i = 0;

    if(!(array = malloc(strlen(str) * sizeof(int)))) return 0x00;
    while(str[c])
    {
        if(str[c] == ch) array[i++] = c;
        c++;
    }
    if(!(tmp = realloc(array, i * sizeof(int)))) return 0x00;
    array = tmp;
    return array;
}

int main(void)
{
    char *str = "foobar foobar";                //'o' occurs at str[1], str[2], str[8], and str[9]
    int *array, b = 0, d;

    if(!(array = chrpos(str, 'o'))) exit(1);    //array[0] = 1, array[1] = 2, array[2] = 8, array[3] = 9

    /*
     * This is okay since I know that 'o'
     * only occures 4 times in str. There
     * may however be cases where I do not
     * know how many times a given char 
     * occurs so I figure that out before
     * utilizing the contents of array.
     * I do this with my function strchroc.
     * Below is a sample of how I would 
     * utilize the data contained within
     * array. This simply prints out str
     * and on a new line prints the given
     * char's location within the str 
     * array
     */

    puts(str);
    while(b < (int) strchroc(str, 'o'))         //loop once for each 'o' 
    {
        for(d = 0; d < (b == 0 ? array[b] : array[b] - array[b - 1] - 1); d++) putc((int) ' ', stdout);
        printf("%d", array[b]);
        b++;
    }
}

出力:

foobar foobar
 12     89

私の唯一の懸念は、これら2つの関数のいずれかが失敗した場合、データを正しく使用する方法がないことです。文字列内の出現回数をchar引数にするchrposことを考えていましたが、それでも両方の関数を呼び出す必要がありました。

配列を構築するために必要な関数が1つだけになるように、これを行う方法について誰かが提案を持っているかどうか疑問に思いました。

私が考えることができる唯一の方法は、charの出現数をに格納し、の位置array[0]array[1] through array[char_occurences]保持することですchar

誰かがより良いアイデアを持っているなら、私はそれを大いに感謝します。

4

2 に答える 2

1

見つかった出現回数も「返す」ように関数を変更できます。C の関数から実際に複数の値を返すことはできませんが、ポインターをパラメーターとして渡し、そのポインターを使用して関数に値を書き留めさせることができます。

int *chrpos(const char *str, char ch, int *found) {
    /* 
    ...
    */
    *found = i;
    return array;
}

constの修飾子は必要ないことに注意してくださいch

于 2012-10-15T15:42:53.743 に答える
1

私のコメントで述べたように、割り当てられたメモリを縮小できない場合に備えて、最初にデータを保存することです:

if (!(tmp = realloc(array, i * sizeof(int))))
  return array;
return (tmp); //array = tmp; is useless

もう少し保護したい場合は、strchroc 関数if (!str) return 0;の先頭に a を追加します。

于 2012-10-15T15:45:45.700 に答える