#include <stdio.h>

enum { LARGEST = 32767 };

int s2int(char s[]);
int getnumber(char prompt[], int imin, int imax, int repeat, int *np);
void sieve(int lim, int an[]);

int main(int argc, char **argv) {
    int i, j, n, *ns;

    if (argc == 2) n = s2int(argv[1]);
    else getnumber("Largest number to test: ", 2, LARGEST, 5, &n);

    if (n < 2 || n > LARGEST) {
        printf("Largest number must in range [2, %d]", LARGEST);
        return 1;
    }

    if ((ns = (int*)malloc(sizeof(int)*(n+1))) == NULL) {
        printf("No enough memory!\n");
        return 2;
    }

    sieve(n, ns);

    for(j = 1, i = 2; i <= n; ++i)
        if (ns[i] == 1) {
            printf("%7d%c", i, (j%8 == 7 ? '\n' : ' '));
            ++j;
        }
    putchar('\n');

    free(ns);
    return 0;
}

int s2int(char s[]) {
    int n;

    for (n = 0; isdigit(*s); ++s)
        n = 10 * n + (*s - '0');

    return n;
}

int getnumber(char prompt[], int imin, int imax, int repeat, int *np) {
    int i;
    *np = 0; // 为了安全，保证函数里一定给 *np 赋了值。

    for (i = 0; repeat <= 0 || i < repeat; ++i) {
        printf("%s", prompt);
        if (scanf("%d", np) != 1 || *np < imin || *np > imax) {
            printf("Wrong input. Correct range [%d, %d].\n",
                   imin, imax);
            while (getchar() != '\n') ;
        }
        else return 1;
    }

    return 0;
}
void sieve(int lim, int an[]) {
    int i, j, upb = sqrt(lim+1);

    an[0] = an[1] = 0; // 建立起初始向量
    for (i = 2; i <= lim; ++i) an[i] = 1;

    for (i = 2; i <= upb; ++i)
        if (an[i] == 1) // i是素数
            for (j = i*2; j <= lim; j += i)
                an[j] = 0; // 这些数都是i的倍数，因此不是素数
}

