2013年5月4日土曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.5(文字ポインタと関数)、演習5-6を解いてみる。

その他参考書籍

演習 5-6.

コード

sample.c

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

#define MAXLINE 1000

int my_getline(char *line, int max);
int atoi(char *s);
void itoa(int n, char *s);
double atof(char *s);
void reverse(char *s);
int strindex(char *s, char *t);

int main()
{
    char pattern[MAXLINE] = "ould";
    char s[MAXLINE];
    int found = 0;

    while (my_getline(s, MAXLINE) > 0)
        if (strindex(s, pattern) >= 0) {
            printf("%s\n", s);
            found++;
        }
    printf("found: %d\n", found);
    printf("atoi\n");
    printf("%d\n", atoi("0"));
    printf("%d\n", atoi("1"));
    printf("%d\n", atoi("-1"));
    printf("%d\n", atoi("2"));
    printf("%d\n", atoi("-2"));
    printf("%d\n", atoi("     -12345     "));
    printf("itoa, reverse\n");
    itoa(0, s);
    printf("%s\n", s);
    itoa(1, s);
    printf("%s\n", s);
    itoa(2, s);
    printf("%s\n", s);
    itoa(-1, s);
    printf("%s\n", s);
    itoa(-2, s);
    printf("%s\n", s);
    itoa(-12345, s);
    printf("%s\n", s);
    printf("atof\n");
    printf("%f\n", atof("0.0"));
    printf("%f\n", atof("1.0"));
    printf("%f\n", atof("12.34"));
    printf("%f\n", atof("-1.0"));
    printf("%f\n", atof("-12.34"));
    printf("%f\n", atof("   -12345.6789     "));

    return 0;
}

int my_getline(char *s, int lim)
{
    int c;
    char *t = s;
    while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
        *s++ = c;
    if (c == '\n')
        *s++ = c;
    *s = '\0';
    return s - t;
}

int atoi(char *s)
{
    int n, sign;
    
    for (; isspace(*s); s++)
        ;
    sign = (*s == '-') ? -1 : 1;
    if (*s == '+' || *s == '-')
        s++;
    for (n = 0; isdigit(*s); s++)
        n = 10 * n + (*s - '0');
    return sign * n;
}

void itoa(int n, char *s)
{
    int sign;
    char *t = s;
    
    if ((sign = n) < 0)
        n = -n;
    do {
        *s++ = n % 10 + '0';
    } while ((n /= 10) > 0);
    if (sign < 0)
        *s++ = '-';
    *s = '\0';
    reverse(t);
}

double atof(char *s)
{
    double val, power;
    int sign;
    for (; isspace(*s); s++)
        ;
    sign = (*s == '-') ? -1 : 1;
    if (*s == '+' || *s == '-')
        s++;
    for (val = 0.0; isdigit(*s); s++)
        val = 10.0 * val + (*s - '0');
    if (*s == '.')
        s++;
    for (power = 1.0; isdigit(*s); s++) {
        val = 10.0 * val + (*s - '0');
        power *= 10.0;
    }
    return sign * val / power;
}

void reverse(char *s)
{
    int c;
    char *t;
    
    for (t = s + (strlen(s) - 1); s < t; s++, t--) {
        c = *s;
        *s = *t;
        *t = c;
    }
}

int strindex(char *s, char *t)
{
    char *i = s;
    char *j, *k;

    for (; *s != '\0'; s++) {
        for (j=s, k=t; *k != '\0' && *j == *k; j++, k++)
            ;
        if (k > t && *k == '\0')
            return s - i;
    }
    return -1;
}

入出力結果(Terminal)

$ cat sample.txt | ./a.out
Ah Love! could you and I with Fate conspire

Would not we shatter it to bits -- and then

Re-mould it nearer to the Heart's Desire!

found: 3
atoi
0
1
-1
2
-2
-12345
itoa, reverse
0
1
2
-1
-2
-12345
atof
0.000000
1.000000
12.340000
-1.000000
-12.340000
-12345.678900
$

逆ポーランド電卓プログラム(ポインタ版)

コード

sample.c

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

#define MAXOP 100
#define NUMBER '0'
#define MAXVAL 100
#define BUFSIZE 100

int getop(char *);
void push(double);
double pop(void);
int getch(void);
void ungetch(int);
int sp = 0;
double val[MAXVAL];
char buf[BUFSIZE];
int bufp = 0;

int main()
{
    int type;
    double op2;
    char s[MAXOP];
        
    while ((type = getop(s)) != EOF) {
        switch (type) {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pop());
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop() / op2);
                else
                    printf("error: zero divisor\n");
                break;
            case '\n':
                printf("\t%.8g\n", pop());
                break;
            default:
                printf("error: unknown command %s\n", s);
                break;
        }
    }
    return 0;
}

void push(double f)
{
    if (sp < MAXVAL)
        val[sp++] = f;
    else
        printf("error: stack full, can't push %g\n", f);
}

double pop(void)
{
    if (sp > 0)
        return val[--sp];
    else {
        printf("error: stack empty\n");
        return 0.0;
    }
}

int getop(char *s)
{
    int c;
    
    *(s + 1) = '\0';
    while((*s = c = getch()) == ' ' || c == '\t')
        ;
    
    if (!isdigit(c) && c != '.')
        return c;
    
    if (isdigit(c))
        while (isdigit(*++s = c = getch()))
            ;
    if (c == '.')
        while (isdigit(*++s = c = getch()))
            ;
    *s = '\0';
    if (c != EOF)
        ungetch(c);
    return NUMBER;
}

int getch(void)
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

入出力結果(Terminal)

$ ./a.out
1 2 - 4 5 + * 
 -9
$

0 コメント:

コメントを投稿