urllibでユーザーエージェントを変更する

Python の urllib.urlopen や urllib.urlretrieve で URL にアクセすると、FancyURLopener オブジェクトが生成されて、これが目的の URL にアクセスする。ユーザーエージェントの値もこの FancyURLopener オブジェクトが持っている。なので、これを変えてやればいい。次のように FancyURLopener のサブクラスを作ってユーザーエージェントの値を設定し、urllib._urlopenr に代入してやればいい。

class Myopener(urllib.FancyURLopener):
    version = "Mozilla"

urllib._urlopener = Myopener()

これで、urllib のデフォルトでは跳ね返されてしまう URL にもアクセスできるようになる。

参考ページ:

 cf. http://docs.python.jp/2/library/urllib.html#urllib._urlopener

文字列の配列

文字列の配列は、しばしば文字テーブルと呼ばれる。次の例は、(ヌル文字を含めて)40文字の文字列を10個格納できる。

char names[10][40];

各文字列にアクセスするには、左の添字だけを書いてやる。例えばキーボードから読み取った文字列を3番目に格納するには、

gets(names[2]);

とする。同様に、5番目の文字列を出力するには、

printf(names[4]);

とする。

次のプログラムは、文字テーブルに 0 から 9 を意味する単語を格納しておき、ユーザーが入力した数値に対応する単語を出力する。

#include

int main(void)
{
    char digits[][10] = {
        "zero",
        "one",
        "two",
        "three",
        "four",
        "five",
        "six",
        "seven",
        "eight",
        "nine"
    };
    char num[2];

    printf("Input a number: ");
    gets(num);
    printf("%s\n", digits[num[0] - '0']);

    return 0;
}

実行例:

takatoh@nightschool $ ./sample_5_5
Input a number: 3
three

配列の初期化

配列も初期化することができる。一般的な形式は次のとおり。

型 変数名[サイズ] = {値のリスト};

「値のリスト」は、定数をカンマで区切ったもの。当然だけどサイズよりも少なくなければいけない。例えば次のように。

int ary[5] = {1, 4, 9, 16, 25};

2次元の場合にも同様に初期化できる。

int sqr[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

文字列の初期化には2通りのやり方がある。1つは、1文字ずつカンマで区切って初期化する方法。この方法だとヌル文字を自分で追加する必要がある。次の例ではヌル文字を追加していない。

char str[3] = {'a', 'b', 'c'};

もう1つは、二重引用符で囲んだ文字列で初期化する方法。この方法だとコンパイラが自動的にヌル文字を追加するので、配列の大きさを初期化しようとする文字列よりも大きくしておく必要がある。

char str[5] = "Herb";

1次元の配列を初期化する場合は、配列のサイズを指定しなくても構わない。次のようにすると、コンパイラが要素数を数えて配列のサイズを決めてくれる。

int pwr[] = {1, 2, 4, 8, 16, 32, 64, 128};

サイズを明示しない配列を、「サイズ指定のない配列(unsized array)」と呼ぶ。
何かの都合で、初期化する要素数が変わっても、数えなおさなくていいので便利。

サイズ指定のない配列は2次元以上の場合には、最初の次元だけサイズを省略することができる。逆に言うと、2次元以上のサイズは省略が出来ない。

int sqr[][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

多次元配列

2次元以上の配列を作ることもできる。単に、サイズの指定を増やせばいいだけだ。

int ary2[4][5];
int ary3[3][3][3];

これらの配列は、メモリ上にはより右に書いてあるの次元の配列が連続して割り当てられる。言い換えると、最も低いアドレスから高いアドレスに順にアクセスしていくと、より右の添字のほうが早く変化する。
4次元以上についても同様。もっとも、そんな次元の配列を使う機会はそうなないだろう。

次のプログラムは、4×5の2次元配列を作って各添字の積を格納してから、行列形式で表示する。

#include

int main(void)
{
    int twod[4][5];
    int i, j;

    for (i = 0; i < 4; i++) {
        for (j = 0; j < 5; j++) {
            twod[i][j] = i * j;
        }
    }
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 5; j++) {
            printf("%d ", twod[i][j]);
        }
        printf("\n");
    }
}
takatoh@nightschool $ ./sample_5_3
0 0 0 0 0 
0 1 2 3 4 
0 2 4 6 8 
0 3 6 9 12