演習5-6 K&R プログラミング言語C

演習5-6

これまでに作った各関数をポインタを使って書き直す。

getline

#include <stdio.h>

#define MAXLINE 1024

int getline(char*, int);

int main(void)
{
    char line[MAXLINE];
    int l, m;

    l = getline(line, MAXLINE);
    printf("\"%s\"'s length => %d\n", line, l);

    m = getline2(line, MAXLINE);
    printf("\"%s\"'s length => %d\n", line, m);

    return 0;
}

int getline(char *s, int lim)
{
    int c, t;

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

実行結果

$ cat hoge.txt
hello
$ ./getline <hoge.txt
"hello
"'s length => 6

atoi

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

int atoi(char*);

int main(void)
{
    char *s = "1280";
    char *t = "-324";

    printf("%s/2 => %d\n", s, atoi(s) / 2);
    printf("%s*2 => %d\n", t, atoi(t) * 2);

    return 0;
}

int atoi(char *s)
{
    int n = 0;
    int sign;

    while (isspace(*s)) /* 空白を飛ばす */
        s++;

    sign = *s == '-' ? -1 : 1;
    if (*s == '-' || *s == '+') /* 符号を飛ばす */
        s++;

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

    return sign * n;
}

実行結果

$ ./atoi
1280/2 => 640
-324*2 => -648

itoa, reverse

#include <stdio.h>

#define MAX 100

void itoa(int, char*);
void reverse(char*);

int main(void)
{
    int i = 123;
    int j = -256;
    char s1[MAX], s2[MAX];

    itoa(i, s1);
    itoa(i*2, s2);
    printf("%s*2 => %s\n", s1, s2);

    itoa(j, s1);
    itoa(j/2, s2);
    printf("%s/2 => %s\n", s1, s2);

    return 0;
}

void itoa(int n, char *s)
{
    int sign;
    char *pt;

    pt = s; /* 先頭アドレスを保存 */
    if ((sign = n) < 0)
        n = -n;

    do {
        *s++ = n % 10 + '0';
    } while ((n /= 10) > 0);

    if (sign < 0)
        *s++ = '-';

    *s = '\0';
    s = pt; /* 先頭アドレスを指し示すように変更 */
    reverse(s);
}

void reverse(char *s)
{
    char *p;
    char tmp;

    p = s;
    while(*s)
        s++;
    s--;
    while (p < s) {
        tmp = *s;
        *s = *p;
        *p = tmp;
        p++;
        s--;
    }
}

実行結果

$ ./itoa
123*2 => 246
-256/2 => -128

以下の itoa はローカルのポインタ変数を返しているので正常に動作しない。

char *itoa(int n)
{
    int sign;
    char _a[MAX];
    char *s, *pt;

    pt = s = _a;
    if ((sign = n) < 0) {
        n = -n;
    }

    do {
        *s++ = n % 10 + '0';
    } while ((n /= 10) > 0);

    if (sign < 0)
        *s++ = '-';

    *s = '\0';
    s = pt;
    reverse(s);

    return s; /* ローカルのポインタ変数を返している */
}

strindex

#include <stdio.h>

int strindex(char*, char*);

int main(void)
{
    char *s = "hello, world";
    char *t = "world";
    char *u = "word";

    printf("strindex(\"%s\", \"%s\"); => %d\n", s, t, strindex(s, t));
    printf("strindex(\"%s\", \"%s\"); => %d\n", s, u, strindex(s, u));

    return 0;
}

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

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

    return -1;
}

実行結果

$ ./strindex
strindex("hello, world", "world"); => 7
strindex("hello, world", "word"); => -1

getop

int getop(char *s)
{
    int c;
    char *pt;

    pt = s;
    while ((*s = c = getch()) == ' ' || c == '\t')
        ;
    *++s = '\0';
    if (!isdigit(c) && c != '.')
        return c; /* 数ではない */
    s = pt;
    if (isdigit(c)) /* 整数部を集める */
        while (isdigit(*++s = c = getch()))
            ;
    if (c == '.') /* 小数部を集める */
        while (isdigit(*++s = c = getch()))
            ;
    *s = '\0';
    if (c != EOF)
        ungetch(c);

    return NUMBER;
}
プログラミング言語C 第2版 ANSI規格準拠
B.W. カーニハン D.M. リッチー
共立出版
売り上げランキング: 9726
«
»