<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Serendip</title>
	<atom:link href="http://www.serendip.ws/feed" rel="self" type="application/rss+xml" />
	<link>http://www.serendip.ws</link>
	<description>Webデザイン・プログラミング</description>
	<lastBuildDate>Thu, 11 Mar 2010 11:37:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>演習7-6 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4486</link>
		<comments>http://www.serendip.ws/archives/4486#comments</comments>
		<pubDate>Thu, 11 Mar 2010 11:37:35 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4486</guid>
		<description><![CDATA[演習7-6
#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;

#define MAXSIZE 1024

int main(int argc, char *argv[])
{
    char *prog = argv[0];
    FILE *fp1, *fp2;
    void filediff(FILE*, FILE*);

    if (argc == 3) {
        if ((fp1 = fopen(argv[1], &#34;r&#34;)) == NULL) {
    [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-6</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>

<span class="PreProc">#define MAXSIZE </span><span class="Constant">1024</span>

<span class="Type">int</span> main(<span class="Type">int</span> argc, <span class="Type">char</span> *argv[])
{
    <span class="Type">char</span> *prog = argv[<span class="Constant">0</span>];
    <span class="Type">FILE</span> *fp1, *fp2;
    <span class="Type">void</span> filediff(<span class="Type">FILE</span>*, <span class="Type">FILE</span>*);

    <span class="Statement">if</span> (argc == <span class="Constant">3</span>) {
        <span class="Statement">if</span> ((fp1 = fopen(argv[<span class="Constant">1</span>], <span class="Constant">&quot;r&quot;</span>)) == <span class="Constant">NULL</span>) {
            fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">: can't open </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, prog, argv[<span class="Constant">1</span>]);
            exit(<span class="Constant">EXIT_FAILURE</span>);
        }
        <span class="Statement">if</span> ((fp2 = fopen(argv[<span class="Constant">2</span>], <span class="Constant">&quot;r&quot;</span>)) == <span class="Constant">NULL</span>) {
            fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">: can't open </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, prog, argv[<span class="Constant">2</span>]);
            exit(<span class="Constant">EXIT_FAILURE</span>);
        }
        filediff(fp1, fp2);
        fclose(fp1);
        fclose(fp2);
    } <span class="Statement">else</span> {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">: 2 file required</span><span class="Special">\n</span><span class="Constant">&quot;</span>, prog);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Type">void</span> filediff(<span class="Type">FILE</span> *fp1, <span class="Type">FILE</span> *fp2)
{
    <span class="Type">char</span> line1[MAXSIZE], line2[MAXSIZE];
    <span class="Type">int</span> count = <span class="Constant">1</span>;

    <span class="Statement">while</span> ((fgets(line1, MAXSIZE, fp1) != <span class="Constant">NULL</span>) &amp;&amp;
           (fgets(line2, MAXSIZE, fp2) != <span class="Constant">NULL</span>)) {
        <span class="Statement">if</span> (strcmp(line1, line2) != <span class="Constant">0</span>) {
            printf(<span class="Constant">&quot;</span><span class="Special">%d</span><span class="Special">\n</span><span class="Special">%s%s</span><span class="Constant">&quot;</span>, count, line1, line2);
            exit(<span class="Constant">EXIT_SUCCESS</span>);
        }
        count++;
    }
}
</pre>
<p>実行結果</p>
<pre>$ cat foo.txt
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
$ cat moo.txt
hello, world
hello, world
hello, world
hello, world!
hello, world
hello, world
$ ./ex7-6 foo.txt moo.txt
4
hello, world
hello, world!
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4486/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-5 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4480</link>
		<comments>http://www.serendip.ws/archives/4480#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:50:20 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4480</guid>
		<description><![CDATA[演習7-5
#include &#60;stdio.h&#62;

#define MAXVAL 100
#define MAXSIZE 100

int sp = 0;
double val[MAXVAL];

void push(double);
double pop(void);

int main(void)
{
    double op1, op2;
    char c, sep;
    char s[MAXSIZE];

    while (scanf(&#34;%s%c&#34;, s, &#38;sep) == 2) {
        if (sscanf(s, &#34;%lf&#34;, &#38;op1) == 1) {
  [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-5</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>

<span class="PreProc">#define MAXVAL </span><span class="Constant">100</span>
<span class="PreProc">#define MAXSIZE </span><span class="Constant">100</span>

<span class="Type">int</span> sp = <span class="Constant">0</span>;
<span class="Type">double</span> val[MAXVAL];

<span class="Type">void</span> push(<span class="Type">double</span>);
<span class="Type">double</span> pop(<span class="Type">void</span>);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">double</span> op1, op2;
    <span class="Type">char</span> c, sep;
    <span class="Type">char</span> s[MAXSIZE];

    <span class="Statement">while</span> (scanf(<span class="Constant">&quot;</span><span class="Special">%s%c</span><span class="Constant">&quot;</span>, s, &amp;sep) == <span class="Constant">2</span>) {
        <span class="Statement">if</span> (sscanf(s, <span class="Constant">&quot;</span><span class="Special">%lf</span><span class="Constant">&quot;</span>, &amp;op1) == <span class="Constant">1</span>) {
            push(op1);
        } <span class="Statement">else</span> <span class="Statement">if</span> (sscanf(s, <span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant">&quot;</span>, &amp;c) == <span class="Constant">1</span>) {
            <span class="Statement">switch</span> (c) {
            <span class="Statement">case</span> <span class="Constant">'+'</span>:
                push(pop() + pop());
                <span class="Statement">break</span>;
            <span class="Statement">case</span> <span class="Constant">'*'</span>:
                push(pop() * pop());
                <span class="Statement">break</span>;
            <span class="Statement">case</span> <span class="Constant">'-'</span>:
                op2 = pop();
                push(pop() - op2);
                <span class="Statement">break</span>;
            <span class="Statement">case</span> <span class="Constant">'/'</span>:
                op2 = pop();
                <span class="Statement">if</span> (op2 == <span class="Constant">0</span>) {
                    fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error : zero divisor</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
                } <span class="Statement">else</span> {
                    push(pop() / op2);
                }
                <span class="Statement">break</span>;
            <span class="Statement">default</span>:
                fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error : unknown command </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, s);
                <span class="Statement">break</span>;
            }
        }
        <span class="Statement">if</span> (sep == <span class="Special">'\n'</span>) {
            printf(<span class="Constant">&quot;</span><span class="Special">\t</span><span class="Special">%.8g</span><span class="Special">\n</span><span class="Constant">&quot;</span>, pop());
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Type">void</span> push(<span class="Type">double</span> f)
{
    <span class="Statement">if</span> (sp &lt; MAXVAL) {
        val[sp++] = f;
    } <span class="Statement">else</span> {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error : stack full, can't push </span><span class="Special">%g</span><span class="Special">\n</span><span class="Constant">&quot;</span>, f);
    }
}

<span class="Type">double</span> pop(<span class="Type">void</span>)
{
    <span class="Statement">if</span> (sp &gt; <span class="Constant">0</span>) {
        <span class="Statement">return</span> val[--sp];
    } <span class="Statement">else</span> {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error : stack empty</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
        <span class="Statement">return</span> <span class="Constant">0.0</span>;
    }
}
</pre>
<p>実行結果</p>
<pre>$ ./calc
10 2 - 5 + 3 / 2 -
        2.3333333
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4480/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-4 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4467</link>
		<comments>http://www.serendip.ws/archives/4467#comments</comments>
		<pubDate>Mon, 08 Mar 2010 15:20:19 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4467</guid>
		<description><![CDATA[演習7-4
minscanf の可変引数はポインタでなければならないので ival, fval はそれぞれ int, float へのポインタ変数とする。
#include &#60;stdio.h&#62;
#include &#60;stdarg.h&#62;

void minscanf(char *fmt, ...);

int main(void)
{
    int day, year;
    char monthname[20];

    minscanf(&#34;%d %s %d&#34;, &#38;day, monthname, &#38;year);
    printf(&#34;day =&#62; %d, monthname =&#62; %s, year =&#62; %d\n&#34;, day, monthname, year);

    return 0;
}

/* minscanf [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-4</h3>
<p><code>minscanf</code> の可変引数は<strong>ポインタでなければならない</strong>ので <code>ival</code>, <code>fval</code> はそれぞれ <code>int</code>, <code>float</code> へのポインタ変数とする。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdarg.h&gt;</span>

<span class="Type">void</span> minscanf(<span class="Type">char</span> *fmt, ...);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">int</span> day, year;
    <span class="Type">char</span> monthname[<span class="Constant">20</span>];

    minscanf(<span class="Constant">&quot;</span><span class="Special">%d</span><span class="Constant"> </span><span class="Special">%s</span><span class="Constant"> </span><span class="Special">%d</span><span class="Constant">&quot;</span>, &amp;day, monthname, &amp;year);
    printf(<span class="Constant">&quot;day =&gt; </span><span class="Special">%d</span><span class="Constant">, monthname =&gt; </span><span class="Special">%s</span><span class="Constant">, year =&gt; </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, day, monthname, year);

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> minscanf : 可変な引数リストをもつ最小の scanf </span><span class="Comment">*/</span>
<span class="Type">void</span> minscanf(<span class="Type">char</span> *fmt, ...)
{
    <span class="Type">va_list</span> ap; <span class="Comment">/*</span><span class="Comment"> 各名なし引数を順々に指す </span><span class="Comment">*/</span>
    <span class="Type">char</span> *p, *sval;
    <span class="Type">int</span> *ival;
    <span class="Type">float</span> *fval;

    va_start(ap, fmt); <span class="Comment">/*</span><span class="Comment"> ap を最初の名なし引数を指すようにする </span><span class="Comment">*/</span>
    <span class="Statement">for</span> (p = fmt; *p; p++) {
        <span class="Statement">if</span> (*p != <span class="Constant">'%'</span>) {
            <span class="Statement">continue</span>;
        }
        <span class="Statement">switch</span> (*++p) {
        <span class="Statement">case</span> <span class="Constant">'d'</span>:
            ival = va_arg(ap, <span class="Type">int</span> *);
            scanf(<span class="Constant">&quot;</span><span class="Special">%d</span><span class="Constant">&quot;</span>, ival);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'f'</span>:
            fval = va_arg(ap, <span class="Type">float</span> *);
            scanf(<span class="Constant">&quot;</span><span class="Special">%f</span><span class="Constant">&quot;</span>, fval);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'s'</span>:
            sval = va_arg(ap, <span class="Type">char</span> *);
            scanf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">&quot;</span>, sval);
            <span class="Statement">break</span>;
        <span class="Statement">default</span>:
            <span class="Statement">break</span>;
        }
    }
}
</pre>
<p>実行結果</p>
<pre>$ ./minscanf
25 Dec 2010
day =&gt; 25, monthname =&gt; Dec, year =&gt; 2010
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4467/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-3 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4453</link>
		<comments>http://www.serendip.ws/archives/4453#comments</comments>
		<pubDate>Mon, 08 Mar 2010 14:23:50 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4453</guid>
		<description><![CDATA[演習7-3
#include &#60;stdio.h&#62;
#include &#60;stdarg.h&#62;

void minprintf(char *fmt, ...);

int main(void)
{
    char *s = &#34;hello&#34;;

    minprintf(&#34;\&#34;%s\&#34; is string of s\n&#34;, s, s);
    minprintf(&#34;%c is \\t\n&#34;, '\t');
    minprintf(&#34;%x is %%x of 'z'\n&#34;, 'z');
    minprintf(&#34;%X is %%X of 'z'\n&#34;, 'z');
    minprintf(&#34;%o is %%o [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-3</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdarg.h&gt;</span>

<span class="Type">void</span> minprintf(<span class="Type">char</span> *fmt, ...);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> *s = <span class="Constant">&quot;hello&quot;</span>;

    minprintf(<span class="Constant">&quot;</span><span class="Special">\&quot;</span><span class="Special">%s</span><span class="Special">\&quot;</span><span class="Constant"> is string of s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, s, s);
    minprintf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant"> is </span><span class="Special">\\</span><span class="Constant">t</span><span class="Special">\n</span><span class="Constant">&quot;</span>, <span class="Special">'\t'</span>);
    minprintf(<span class="Constant">&quot;</span><span class="Special">%x</span><span class="Constant"> is </span><span class="Special">%%</span><span class="Constant">x of 'z'</span><span class="Special">\n</span><span class="Constant">&quot;</span>, <span class="Constant">'z'</span>);
    minprintf(<span class="Constant">&quot;</span><span class="Special">%X</span><span class="Constant"> is </span><span class="Special">%%</span><span class="Constant">X of 'z'</span><span class="Special">\n</span><span class="Constant">&quot;</span>, <span class="Constant">'z'</span>);
    minprintf(<span class="Constant">&quot;</span><span class="Special">%o</span><span class="Constant"> is </span><span class="Special">%%</span><span class="Constant">o of 'z'</span><span class="Special">\n</span><span class="Constant">&quot;</span>, <span class="Constant">'z'</span>);
    minprintf(<span class="Constant">&quot;</span><span class="Special">%p</span><span class="Constant"> is pointer of </span><span class="Special">\&quot;</span><span class="Special">%s</span><span class="Special">\&quot;\n</span><span class="Constant">&quot;</span>, s, s);

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> minprintf : 可変な引数リストをもつ最小の printf </span><span class="Comment">*/</span>
<span class="Type">void</span> minprintf(<span class="Type">char</span> *fmt, ...)
{
    <span class="Type">va_list</span> ap; <span class="Comment">/*</span><span class="Comment"> 各名なし引数を順々に指す </span><span class="Comment">*/</span>
    <span class="Type">char</span> *p, *sval;
    <span class="Type">int</span> ival;
    <span class="Type">unsigned</span> <span class="Type">int</span> uval;
    <span class="Type">double</span> dval;
    <span class="Type">void</span> *pval;

    va_start(ap, fmt); <span class="Comment">/*</span><span class="Comment"> ap を最初の名なし引数を指すようにする </span><span class="Comment">*/</span>
    <span class="Statement">for</span> (p = fmt; *p; p++) {
        <span class="Statement">if</span> (*p != <span class="Constant">'%'</span>) {
            putchar(*p);
            <span class="Statement">continue</span>;
        }
        <span class="Statement">switch</span> (*++p) {
        <span class="Statement">case</span> <span class="Constant">'d'</span>:
            ival = va_arg(ap, <span class="Type">int</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%d</span><span class="Constant">&quot;</span>, ival);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'f'</span>:
            dval = va_arg(ap, <span class="Type">double</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%f</span><span class="Constant">&quot;</span>, dval);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'s'</span>:
            <span class="Statement">for</span> (sval = va_arg(ap, <span class="Type">char</span> *); *sval; sval++) {
                putchar(*sval);
            }
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'c'</span>:
            ival = va_arg(ap, <span class="Type">int</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant">&quot;</span>, ival);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'x'</span>:
            uval = va_arg(ap, <span class="Type">unsigned</span> <span class="Type">int</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%x</span><span class="Constant">&quot;</span>, uval);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'X'</span>:
            uval = va_arg(ap, <span class="Type">unsigned</span> <span class="Type">int</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%X</span><span class="Constant">&quot;</span>, uval);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'o'</span>:
            uval = va_arg(ap, <span class="Type">unsigned</span> <span class="Type">int</span>);
            printf(<span class="Constant">&quot;</span><span class="Special">%o</span><span class="Constant">&quot;</span>, uval);
            <span class="Statement">break</span>;
        <span class="Statement">case</span> <span class="Constant">'p'</span>:
            pval = va_arg(ap, <span class="Type">void</span> *);
            printf(<span class="Constant">&quot;</span><span class="Special">%p</span><span class="Constant">&quot;</span>, pval);
            <span class="Statement">break</span>;
        <span class="Statement">default</span>:
            putchar(*p);
            <span class="Statement">break</span>;
        }
    }
    va_end(ap); <span class="Comment">/*</span><span class="Comment"> 終わったときクリーンアップ </span><span class="Comment">*/</span>
}
</pre>
<p>実行結果</p>
<pre>$ ./minprintf
&quot;hello&quot; is string of s
         is \t
7a is %x of 'z'
7A is %X of 'z'
172 is %o of 'z'
0x100000eac is pointer of &quot;hello&quot;
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4453/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-2 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4448</link>
		<comments>http://www.serendip.ws/archives/4448#comments</comments>
		<pubDate>Sun, 07 Mar 2010 12:42:03 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4448</guid>
		<description><![CDATA[演習7-2
#include &#60;stdio.h&#62;
#include &#60;ctype.h&#62;

int main(int argc, char *argv[])
{
    int fmtype = 0;
    int c;
    char *(format[2]) = { &#34;0x%06x &#34;, &#34;%03o &#34; };

    while (--argc &#62; 0 &#38;&#38; (*++argv)[0] == '-') {
        while ((c = *++argv[0]) != [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-2</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;ctype.h&gt;</span>

<span class="Type">int</span> main(<span class="Type">int</span> argc, <span class="Type">char</span> *argv[])
{
    <span class="Type">int</span> fmtype = <span class="Constant">0</span>;
    <span class="Type">int</span> c;
    <span class="Type">char</span> *(format[<span class="Constant">2</span>]) = { <span class="Constant">&quot;0x</span><span class="Special">%06x</span><span class="Constant"> &quot;</span>, <span class="Constant">&quot;</span><span class="Special">%03o</span><span class="Constant"> &quot;</span> };

    <span class="Statement">while</span> (--argc &gt; <span class="Constant">0</span> &amp;&amp; (*++argv)[<span class="Constant">0</span>] == <span class="Constant">'-'</span>) {
        <span class="Statement">while</span> ((c = *++argv[<span class="Constant">0</span>]) != <span class="Special">'\0'</span>) {
            <span class="Statement">switch</span> (c) {
            <span class="Statement">case</span> <span class="Constant">'o'</span>:
                fmtype = <span class="Constant">1</span>;
                <span class="Statement">break</span>;
            <span class="Statement">case</span> <span class="Constant">'x'</span>:
                fmtype = <span class="Constant">0</span>;
                <span class="Statement">break</span>;
            <span class="Statement">default</span>:
                fmtype = <span class="Constant">0</span>;
                <span class="Statement">break</span>;
            }
        }
    }

    <span class="Statement">while</span> ((c = getchar()) != <span class="Constant">EOF</span>) {
        <span class="Statement">if</span> (isprint(c) || isspace(c)) {
            putchar(c);
        } <span class="Statement">else</span> {
            printf(format[fmtype], c);
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4448/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-1 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4444</link>
		<comments>http://www.serendip.ws/archives/4444#comments</comments>
		<pubDate>Sat, 06 Mar 2010 14:06:34 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4444</guid>
		<description><![CDATA[演習7-1
#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;ctype.h&#62;

enum { TOLOWER, TOUPPER };

int main(int argc, char *argv[])
{
    int c;
    int prog_type;
    int (*conv[2])(int) = { tolower, toupper };

    if (strcmp(argv[0], &#34;./tolower&#34;) == 0) {
        prog_type = TOLOWER;
    [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-1</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;ctype.h&gt;</span>

<span class="Type">enum</span> { TOLOWER, TOUPPER };

<span class="Type">int</span> main(<span class="Type">int</span> argc, <span class="Type">char</span> *argv[])
{
    <span class="Type">int</span> c;
    <span class="Type">int</span> prog_type;
    <span class="Type">int</span> (*conv[<span class="Constant">2</span>])(<span class="Type">int</span>) = { tolower, toupper };

    <span class="Statement">if</span> (strcmp(argv[<span class="Constant">0</span>], <span class="Constant">&quot;./tolower&quot;</span>) == <span class="Constant">0</span>) {
        prog_type = TOLOWER;
    } <span class="Statement">else</span> <span class="Statement">if</span> (strcmp(argv[<span class="Constant">0</span>], <span class="Constant">&quot;./toupper&quot;</span>) == <span class="Constant">0</span>) {
        prog_type = TOUPPER;
    } <span class="Statement">else</span> {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error : Unknown program name </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, argv[<span class="Constant">0</span>]);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }

    <span class="Statement">while</span> ((c = getchar()) != <span class="Constant">EOF</span>) {
        putchar(conv[prog_type](c));
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}
</pre>
<p>実行結果</p>
<pre>$ cat sample.txt
Hello, World!
$ ./tolower &lt;sample.txt
hello, world!
$ ./toupper &lt;sample.txt
HELLO, WORLD!
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4444/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習6-6 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4422</link>
		<comments>http://www.serendip.ws/archives/4422#comments</comments>
		<pubDate>Fri, 05 Mar 2010 14:11:10 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4422</guid>
		<description><![CDATA[演習6-6
#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;ctype.h&#62;

#define MAXWORD 100
#define BUFSIZE 100
#define HASHSIZE 101

char buf[BUFSIZE];  /* ungetch 用のバッファ */
int bufp = 0;       /* buf 中の次の空き位置 */

struct nlist { /* テーブルの項目 */
    struct nlist *next; /* チェインの中の次の項目 */
    char *name;       [...]]]></description>
			<content:encoded><![CDATA[<h3>演習6-6</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;ctype.h&gt;</span>

<span class="PreProc">#define MAXWORD </span><span class="Constant">100</span>
<span class="PreProc">#define BUFSIZE </span><span class="Constant">100</span>
<span class="PreProc">#define HASHSIZE </span><span class="Constant">101</span>

<span class="Type">char</span> buf[BUFSIZE];  <span class="Comment">/*</span><span class="Comment"> ungetch 用のバッファ </span><span class="Comment">*/</span>
<span class="Type">int</span> bufp = <span class="Constant">0</span>;       <span class="Comment">/*</span><span class="Comment"> buf 中の次の空き位置 </span><span class="Comment">*/</span>

<span class="Type">struct</span> nlist { <span class="Comment">/*</span><span class="Comment"> テーブルの項目 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> nlist *next; <span class="Comment">/*</span><span class="Comment"> チェインの中の次の項目 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *name;         <span class="Comment">/*</span><span class="Comment"> 定義された名前 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *defn;         <span class="Comment">/*</span><span class="Comment"> 置換テキスト </span><span class="Comment">*/</span>
};

<span class="Type">static</span> <span class="Type">struct</span> nlist *hashtab[HASHSIZE]; <span class="Comment">/*</span><span class="Comment"> ポインタのテーブル </span><span class="Comment">*/</span>

<span class="Type">unsigned</span> hash(<span class="Type">char</span> *);
<span class="Type">struct</span> nlist *lookup(<span class="Type">char</span> *);
<span class="Type">struct</span> nlist *install(<span class="Type">char</span> *, <span class="Type">char</span> *);
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *);
<span class="Type">char</span> *search_defn(<span class="Type">char</span> *);
<span class="Type">void</span> undef(<span class="Type">char</span> *);
<span class="Type">int</span> getword(<span class="Type">char</span> *, <span class="Type">int</span>);
<span class="Type">int</span> is_legal_char(<span class="Type">char</span>);

<span class="Type">enum</span> { LABEL, NAME, DEFINITION };

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> word[MAXWORD];
    <span class="Type">int</span> cond = LABEL;
    <span class="Type">char</span> *name;
    <span class="Type">char</span> *defn;

    <span class="Statement">while</span> (getword(word, MAXWORD) != <span class="Constant">EOF</span>) {
        <span class="Statement">if</span> (is_legal_char(word[<span class="Constant">0</span>])) {
            <span class="Statement">if</span> (cond == LABEL &amp;&amp; strcmp(word, <span class="Constant">&quot;#define&quot;</span>) == <span class="Constant">0</span>) {
                cond = NAME;
            } <span class="Statement">else</span> <span class="Statement">if</span> (cond == NAME) {
                name = strdup(word);
                cond = DEFINITION;
            } <span class="Statement">else</span> <span class="Statement">if</span> (cond == DEFINITION) {
                defn = strdup(word);
                cond = LABEL;
                install(name, defn);
            }

            <span class="Statement">if</span> (cond == LABEL) {
                printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name, search_defn(name));
            }
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> undef : ハッシュテーブルから名前と定義を削除する </span><span class="Comment">*/</span>
<span class="Type">void</span> undef(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np1, *np2; <span class="Comment">/*</span><span class="Comment"> np1 は削除対象のポインタ </span><span class="Comment">*/</span>
    <span class="Type">unsigned</span> hashval = hash(s);

    <span class="Statement">for</span> (np1 = np2 = hashtab[hashval]; np1 != <span class="Constant">NULL</span>; np2 = np1, np1 = np1-&gt;next) {
        <span class="Statement">if</span> (strcmp(s, np1-&gt;name) == <span class="Constant">0</span>) { <span class="Comment">/*</span><span class="Comment"> s がハッシュテーブルに見つかった </span><span class="Comment">*/</span>
            <span class="Statement">if</span> (np1 == np2) { <span class="Comment">/*</span><span class="Comment"> リストの先頭の場合 </span><span class="Comment">*/</span>
                hashtab[hashval] = np1-&gt;next;
            } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> np2 が np1 の前の場合 </span><span class="Comment">*/</span>
                np2-&gt;next = np1-&gt;next;
            }
            free(np1-&gt;name);
            free(np1-&gt;defn);
            free(np1);
            <span class="Statement">break</span>;
        }
    }

}

<span class="Comment">/*</span><span class="Comment"> search_defn : 名前文字列 s からハッシュに登録されている定義文字列を探す </span><span class="Comment">*/</span>
<span class="Type">char</span> *search_defn(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np;

    <span class="Statement">if</span> ((np = lookup(s)) != <span class="Constant">NULL</span>) { <span class="Comment">/*</span><span class="Comment"> 見つかった </span><span class="Comment">*/</span>
        <span class="Statement">return</span> np-&gt;defn;
    } <span class="Statement">else</span> {
        <span class="Statement">return</span> <span class="Constant">&quot;not defined.&quot;</span>;
    }
}

<span class="Comment">/*</span><span class="Comment"> hash : 文字列 s に対しハッシュの値を求める </span><span class="Comment">*/</span>
<span class="Type">unsigned</span> hash(<span class="Type">char</span> *s)
{
    <span class="Type">unsigned</span> hashval;

    <span class="Statement">for</span> (hashval = <span class="Constant">0</span>; *s != <span class="Special">'\0'</span>; s++) {
        hashval = *s + <span class="Constant">31</span> *hashval;
    }
    <span class="Statement">return</span> hashval % HASHSIZE;
}

<span class="Comment">/*</span><span class="Comment"> lookup : hashtab の中で s を探す </span><span class="Comment">*/</span>
<span class="Type">struct</span> nlist *lookup(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np;

    <span class="Statement">for</span> (np = hashtab[hash(s)]; np != <span class="Constant">NULL</span>; np = np-&gt;next) {
        <span class="Statement">if</span> (strcmp(s, np-&gt;name) == <span class="Constant">0</span>) {
            <span class="Statement">return</span> np; <span class="Comment">/*</span><span class="Comment"> 見つかった </span><span class="Comment">*/</span>
        }
    }
    <span class="Statement">return</span> <span class="Constant">NULL</span>; <span class="Comment">/*</span><span class="Comment"> 見つからない </span><span class="Comment">*/</span>
}

<span class="Comment">/*</span><span class="Comment"> install : hashtab の中に (name, defn) を置く </span><span class="Comment">*/</span>
<span class="Type">struct</span> nlist *install(<span class="Type">char</span> *name, <span class="Type">char</span> *defn)
{
    <span class="Type">struct</span> nlist *np;
    <span class="Type">unsigned</span> hashval;

    <span class="Statement">if</span> ((np = lookup(name)) == <span class="Constant">NULL</span>) { <span class="Comment">/*</span><span class="Comment"> 見つからなかった </span><span class="Comment">*/</span>
        np = (<span class="Type">struct</span> nlist *) malloc(<span class="Statement">sizeof</span>(*np));
        <span class="Statement">if</span> (np == <span class="Constant">NULL</span> || (np-&gt;name = my_strdup(name)) == <span class="Constant">NULL</span>) {
            <span class="Statement">return</span> <span class="Constant">NULL</span>;
        }
        hashval = hash(name);
        np-&gt;next = hashtab[hashval];
        hashtab[hashval] = np;
    } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> すでにある </span><span class="Comment">*/</span>
        free((<span class="Type">void</span> *) np-&gt;defn); <span class="Comment">/*</span><span class="Comment"> 以前の defn を解放する </span><span class="Comment">*/</span>
    }
    <span class="Statement">if</span> ((np-&gt;defn = my_strdup(defn)) == <span class="Constant">NULL</span>) {
        <span class="Statement">return</span> <span class="Constant">NULL</span>;
    }
    <span class="Statement">return</span> np;
}

<span class="Comment">/*</span><span class="Comment"> my_strdup : s の複製を作る </span><span class="Comment">*/</span>
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *s)
{
    <span class="Type">char</span> *p;

    p = (<span class="Type">char</span> *) malloc(strlen(s)+<span class="Constant">1</span>); <span class="Comment">/*</span><span class="Comment"> + 1 for '\0' </span><span class="Comment">*/</span>
    <span class="Statement">if</span> (p != <span class="Constant">NULL</span>) {
        strcpy(p, s);
    }
    <span class="Statement">return</span> p;
}

<span class="Comment">/*</span><span class="Comment"> #define に利用できる文字かチェックする </span><span class="Comment">*/</span>
<span class="Type">int</span> is_legal_char(<span class="Type">char</span> c)
{
    <span class="Statement">if</span> (isalnum(c)) {
        <span class="Statement">return</span> <span class="Constant">1</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> (c == <span class="Constant">'_'</span>) {
        <span class="Statement">return</span> <span class="Constant">1</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> (c == <span class="Constant">'#'</span>) {
        <span class="Statement">return</span> <span class="Constant">1</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> (c == <span class="Constant">'&quot;'</span>) {
        <span class="Statement">return</span> <span class="Constant">1</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> (c == <span class="Special">'\''</span>) {
        <span class="Statement">return</span> <span class="Constant">1</span>;
    } <span class="Statement">else</span> {
        <span class="Statement">return</span> <span class="Constant">0</span>;
    }
}

<span class="Comment">/*</span><span class="Comment"> getword : 入力から次の語または文字を求める </span><span class="Comment">*/</span>
<span class="Type">int</span> getword(<span class="Type">char</span> *word, <span class="Type">int</span> lim)
{
    <span class="Type">int</span> c, getch(<span class="Type">void</span>);
    <span class="Type">void</span> ungetch(<span class="Type">int</span>);
    <span class="Type">char</span> *w = word;

    <span class="Statement">while</span> (isspace(c = getch()))
        ;
    <span class="Statement">if</span> (c != <span class="Constant">EOF</span>) {
        *w++ = c;
    }
    <span class="Statement">if</span> (!is_legal_char(c)) {
        *w = <span class="Special">'\0'</span>;
        <span class="Statement">return</span> c;
    }
    <span class="Statement">for</span> ( ; --lim &gt; <span class="Constant">0</span>; w++) {
        <span class="Statement">if</span> (!is_legal_char(*w = getch())) {
            ungetch(*w);
            <span class="Statement">break</span>;
        }
    }
    *w = <span class="Special">'\0'</span>;
    <span class="Statement">return</span> word[<span class="Constant">0</span>];
}

<span class="Type">int</span> getch(<span class="Type">void</span>) <span class="Comment">/*</span><span class="Comment"> (押し戻された可能性もある) 1文字をとってくる </span><span class="Comment">*/</span>
{
    <span class="Statement">return</span> (bufp &gt; <span class="Constant">0</span>) ? buf[--bufp] : getchar();
}

<span class="Type">void</span> ungetch(<span class="Type">int</span> c) <span class="Comment">/*</span><span class="Comment"> 文字を入力に押し戻す </span><span class="Comment">*/</span>
{
    <span class="Statement">if</span> (bufp &gt; BUFSIZE)
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;ungetch : too many characters</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    <span class="Statement">else</span>
        buf[bufp++] = c;
}
</pre>
<p>実行結果</p>
<pre>$ cat sample.txt
#define MAX 1000
#define MIN 100
#define MSG &quot;hello&quot;
#define IS_WORD 1
$ ./ex6-6 &lt;sample.txt
MAX is 1000
MIN is 100
MSG is &quot;hello&quot;
IS_WORD is 1
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4422/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習6-5 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4419</link>
		<comments>http://www.serendip.ws/archives/4419#comments</comments>
		<pubDate>Thu, 04 Mar 2010 14:10:56 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4419</guid>
		<description><![CDATA[演習6-5
削除する名前と定義を見つけてテーブル（連結リスト）のリンクを繋ぎ直して、名前と定義と nlist をメモリから解放する。
見つかった場所がテーブルの先頭であれば、テーブルの先頭を次の項目を指すように変更する。
#include &#60;stdio.h&#62;]]></description>
			<content:encoded><![CDATA[<h3>演習6-5</h3>
<p>削除する名前と定義を見つけてテーブル（連結リスト）のリンクを繋ぎ直して、名前と定義と <code>nlist</code> をメモリから解放する。<br />
見つかった場所がテーブルの先頭であれば、テーブルの先頭を次の項目を指すように変更する。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>

<span class="PreProc">#define HASHSIZE </span><span class="Constant">101</span>

<span class="Type">struct</span> nlist { <span class="Comment">/*</span><span class="Comment"> テーブルの項目 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> nlist *next; <span class="Comment">/*</span><span class="Comment"> チェインの中の次の項目 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *name;         <span class="Comment">/*</span><span class="Comment"> 定義された名前 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *defn;         <span class="Comment">/*</span><span class="Comment"> 置換テキスト </span><span class="Comment">*/</span>
};

<span class="Type">static</span> <span class="Type">struct</span> nlist *hashtab[HASHSIZE]; <span class="Comment">/*</span><span class="Comment"> ポインタのテーブル </span><span class="Comment">*/</span>

<span class="Type">unsigned</span> hash(<span class="Type">char</span> *);
<span class="Type">struct</span> nlist *lookup(<span class="Type">char</span> *);
<span class="Type">struct</span> nlist *install(<span class="Type">char</span> *, <span class="Type">char</span> *);
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *);
<span class="Type">char</span> *search_defn(<span class="Type">char</span> *);
<span class="Type">void</span> undef(<span class="Type">char</span> *);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> *name1 = <span class="Constant">&quot;IN&quot;</span>;
    <span class="Type">char</span> *defn1 = <span class="Constant">&quot;1&quot;</span>;
    <span class="Type">char</span> *name2 = <span class="Constant">&quot;OUT&quot;</span>;
    <span class="Type">char</span> *defn2 = <span class="Constant">&quot;2&quot;</span>;
    <span class="Type">char</span> *name3 = <span class="Constant">&quot;SOME&quot;</span>;
    <span class="Type">char</span> *defn3 = <span class="Constant">&quot;3&quot;</span>;
    <span class="Type">char</span> *defn4 = <span class="Constant">&quot;4&quot;</span>;

    install(name1, defn1);
    install(name2, defn2);
    install(name3, defn3);
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name1, search_defn(name1));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name2, search_defn(name2));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name3, search_defn(name3));
    printf(<span class="Constant">&quot;----------</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    undef(name2); <span class="Comment">/*</span><span class="Comment"> name2 の名前と定義を削除 </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name1, search_defn(name1));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name2, search_defn(name2));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name3, search_defn(name3));
    printf(<span class="Constant">&quot;----------</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    install(name2, defn4); <span class="Comment">/*</span><span class="Comment"> name2 の名前と定義を再登録 </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name1, search_defn(name1));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name2, search_defn(name2));
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant"> is </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name3, search_defn(name3));

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> undef : ハッシュテーブルから名前と定義を削除する </span><span class="Comment">*/</span>
<span class="Type">void</span> undef(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np1, *np2; <span class="Comment">/*</span><span class="Comment"> np1 は削除対象のポインタ </span><span class="Comment">*/</span>
    <span class="Type">unsigned</span> hashval = hash(s);

    <span class="Statement">for</span> (np1 = np2 = hashtab[hashval]; np1 != <span class="Constant">NULL</span>; np2 = np1, np1 = np1-&gt;next) {
        <span class="Statement">if</span> (strcmp(s, np1-&gt;name) == <span class="Constant">0</span>) { <span class="Comment">/*</span><span class="Comment"> s がハッシュテーブルに見つかった </span><span class="Comment">*/</span>
            <span class="Statement">if</span> (np1 == np2) { <span class="Comment">/*</span><span class="Comment"> リストの先頭の場合 </span><span class="Comment">*/</span>
                hashtab[hashval] = np1-&gt;next;
            } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> np2 が np1 の前の場合 </span><span class="Comment">*/</span>
                np2-&gt;next = np1-&gt;next;
            }
            free(np1-&gt;name);
            free(np1-&gt;defn);
            free(np1);
            <span class="Statement">break</span>;
        }
    }

}

<span class="Comment">/*</span><span class="Comment"> search_defn : 名前文字列 s からハッシュに登録されている定義文字列を探す </span><span class="Comment">*/</span>
<span class="Type">char</span> *search_defn(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np;

    <span class="Statement">if</span> ((np = lookup(s)) != <span class="Constant">NULL</span>) { <span class="Comment">/*</span><span class="Comment"> 見つかった </span><span class="Comment">*/</span>
        <span class="Statement">return</span> np-&gt;defn;
    } <span class="Statement">else</span> {
        <span class="Statement">return</span> <span class="Constant">&quot;not defined.&quot;</span>;
    }
}

<span class="Comment">/*</span><span class="Comment"> hash : 文字列 s に対しハッシュの値を求める </span><span class="Comment">*/</span>
<span class="Type">unsigned</span> hash(<span class="Type">char</span> *s)
{
    <span class="Type">unsigned</span> hashval;

    <span class="Statement">for</span> (hashval = <span class="Constant">0</span>; *s != <span class="Special">'\0'</span>; s++) {
        hashval = *s + <span class="Constant">31</span> *hashval;
    }
    <span class="Statement">return</span> hashval % HASHSIZE;
}

<span class="Comment">/*</span><span class="Comment"> lookup : hashtab の中で s を探す </span><span class="Comment">*/</span>
<span class="Type">struct</span> nlist *lookup(<span class="Type">char</span> *s)
{
    <span class="Type">struct</span> nlist *np;

    <span class="Statement">for</span> (np = hashtab[hash(s)]; np != <span class="Constant">NULL</span>; np = np-&gt;next) {
        <span class="Statement">if</span> (strcmp(s, np-&gt;name) == <span class="Constant">0</span>) {
            <span class="Statement">return</span> np; <span class="Comment">/*</span><span class="Comment"> 見つかった </span><span class="Comment">*/</span>
        }
    }
    <span class="Statement">return</span> <span class="Constant">NULL</span>; <span class="Comment">/*</span><span class="Comment"> 見つからない </span><span class="Comment">*/</span>
}

<span class="Comment">/*</span><span class="Comment"> install : hashtab の中に (name, defn) を置く </span><span class="Comment">*/</span>
<span class="Type">struct</span> nlist *install(<span class="Type">char</span> *name, <span class="Type">char</span> *defn)
{
    <span class="Type">struct</span> nlist *np;
    <span class="Type">unsigned</span> hashval;

    <span class="Statement">if</span> ((np = lookup(name)) == <span class="Constant">NULL</span>) { <span class="Comment">/*</span><span class="Comment"> 見つからなかった </span><span class="Comment">*/</span>
        np = (<span class="Type">struct</span> nlist *) malloc(<span class="Statement">sizeof</span>(*np));
        <span class="Statement">if</span> (np == <span class="Constant">NULL</span> || (np-&gt;name = my_strdup(name)) == <span class="Constant">NULL</span>) {
            <span class="Statement">return</span> <span class="Constant">NULL</span>;
        }
        hashval = hash(name);
        np-&gt;next = hashtab[hashval];
        hashtab[hashval] = np;
    } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> すでにある </span><span class="Comment">*/</span>
        free((<span class="Type">void</span> *) np-&gt;defn); <span class="Comment">/*</span><span class="Comment"> 以前の defn を解放する </span><span class="Comment">*/</span>
    }
    <span class="Statement">if</span> ((np-&gt;defn = my_strdup(defn)) == <span class="Constant">NULL</span>) {
        <span class="Statement">return</span> <span class="Constant">NULL</span>;
    }
    <span class="Statement">return</span> np;
}

<span class="Comment">/*</span><span class="Comment"> my_strdup : s の複製を作る </span><span class="Comment">*/</span>
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *s)
{
    <span class="Type">char</span> *p;

    p = (<span class="Type">char</span> *) malloc(strlen(s)+<span class="Constant">1</span>); <span class="Comment">/*</span><span class="Comment"> + 1 for '\0' </span><span class="Comment">*/</span>
    <span class="Statement">if</span> (p != <span class="Constant">NULL</span>) {
        strcpy(p, s);
    }
    <span class="Statement">return</span> p;
}
</pre>
<p>実行結果</p>
<pre>$ ./undef
IN is 1
OUT is 2
SOME is 3
----------
IN is 1
OUT is not defined.
SOME is 3
----------
IN is 1
OUT is 4
SOME is 3
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4419/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習6-4 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4403</link>
		<comments>http://www.serendip.ws/archives/4403#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:44:56 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4403</guid>
		<description><![CDATA[演習6-4
単語の発生頻度順に単語リストを保存するツリーを作成する構造体 freq を定義する。
tnode から freq へデータをコピーして freq を印字する。
#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;ctype.h&#62;
#include &#60;string.h&#62;

#define MAXWORD 100
#define BUFSIZE 100

char buf[BUFSIZE];  /* ungetch 用のバッファ */
int bufp = 0;       /* buf 中の次の空き位置 */

struct tnode {           /* 木のノード */
    char *word; [...]]]></description>
			<content:encoded><![CDATA[<h3>演習6-4</h3>
<p>単語の発生頻度順に単語リストを保存するツリーを作成する構造体 <code>freq</code> を定義する。<br />
<code>tnode</code> から <code>freq</code> へデータをコピーして <code>freq</code> を印字する。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;ctype.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>

<span class="PreProc">#define MAXWORD </span><span class="Constant">100</span>
<span class="PreProc">#define BUFSIZE </span><span class="Constant">100</span>

<span class="Type">char</span> buf[BUFSIZE];  <span class="Comment">/*</span><span class="Comment"> ungetch 用のバッファ </span><span class="Comment">*/</span>
<span class="Type">int</span> bufp = <span class="Constant">0</span>;       <span class="Comment">/*</span><span class="Comment"> buf 中の次の空き位置 </span><span class="Comment">*/</span>

<span class="Type">struct</span> tnode {           <span class="Comment">/*</span><span class="Comment"> 木のノード </span><span class="Comment">*/</span>
    <span class="Type">char</span> *word;          <span class="Comment">/*</span><span class="Comment"> テキストへのポインタ </span><span class="Comment">*/</span>
    <span class="Type">int</span> count;           <span class="Comment">/*</span><span class="Comment"> 出現回数 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> tnode *left;  <span class="Comment">/*</span><span class="Comment"> 左の子供 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> tnode *right; <span class="Comment">/*</span><span class="Comment"> 右の子供 </span><span class="Comment">*/</span>
};

<span class="Type">struct</span> freq {               <span class="Comment">/*</span><span class="Comment"> 単語の発生頻度順のノード </span><span class="Comment">*/</span>
    <span class="Type">char</span> *(word[MAXWORD]);  <span class="Comment">/*</span><span class="Comment"> 単語リスト配列へのポインタ </span><span class="Comment">*/</span>
    <span class="Type">int</span> word_count;         <span class="Comment">/*</span><span class="Comment"> 単語リストのサイズ </span><span class="Comment">*/</span>
    <span class="Type">int</span> count;              <span class="Comment">/*</span><span class="Comment"> 単語の発生頻度数 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> freq *left;      <span class="Comment">/*</span><span class="Comment"> 左の子ノード </span><span class="Comment">*/</span>
    <span class="Type">struct</span> freq *right;     <span class="Comment">/*</span><span class="Comment"> 右の子ノード </span><span class="Comment">*/</span>
};

<span class="Type">struct</span> tnode *addtree(<span class="Type">struct</span> tnode *, <span class="Type">char</span> *);
<span class="Type">void</span> treeprint(<span class="Type">struct</span> tnode *);
<span class="Type">int</span> getword(<span class="Type">char</span> *, <span class="Type">int</span>);
<span class="Type">struct</span> freq *falloc(<span class="Type">void</span>);
<span class="Type">struct</span> freq *tnode_cp_to_freq(<span class="Type">struct</span> tnode *, <span class="Type">struct</span> freq *);
<span class="Type">struct</span> freq *word_cp_to_freq(<span class="Type">struct</span> tnode *, <span class="Type">struct</span> freq *);
<span class="Type">void</span> freqprint(<span class="Type">struct</span> freq *);

<span class="Comment">/*</span><span class="Comment"> 単語の頻度カウント </span><span class="Comment">*/</span>
<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">struct</span> tnode *root;
    <span class="Type">struct</span> freq *frequency;
    <span class="Type">char</span> word[MAXWORD];

    root = <span class="Constant">NULL</span>;
    <span class="Statement">while</span> (getword(word, MAXWORD) != <span class="Constant">EOF</span>) {
        <span class="Statement">if</span> (isalpha(word[<span class="Constant">0</span>])) {
            root = addtree(root, word);
        }
    }

    frequency = <span class="Constant">NULL</span>;
    frequency = tnode_cp_to_freq(root, frequency);
    freqprint(frequency);

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Type">struct</span> tnode *talloc(<span class="Type">void</span>);
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *);

<span class="Comment">/*</span><span class="Comment"> addtree : p の位置あるいはその下に w のノードを加える </span><span class="Comment">*/</span>
<span class="Type">struct</span> tnode *addtree(<span class="Type">struct</span> tnode *p, <span class="Type">char</span> *w)
{
    <span class="Type">int</span> cond;

    <span class="Statement">if</span> (p == <span class="Constant">NULL</span>) {  <span class="Comment">/*</span><span class="Comment"> 新しい単語がきた </span><span class="Comment">*/</span>
        p = talloc(); <span class="Comment">/*</span><span class="Comment"> 新しいノードをつくる </span><span class="Comment">*/</span>
        p-&gt;word = my_strdup(w);
        p-&gt;count = <span class="Constant">1</span>;
        p-&gt;left = p-&gt;right = <span class="Constant">NULL</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> ((cond = strcmp(w, p-&gt;word)) == <span class="Constant">0</span>) {
        p-&gt;count++;         <span class="Comment">/*</span><span class="Comment"> 繰り返された単語 </span><span class="Comment">*/</span>
    } <span class="Statement">else</span> <span class="Statement">if</span> (cond &lt; <span class="Constant">0</span>) {  <span class="Comment">/*</span><span class="Comment"> より小さければ、左部分木へ </span><span class="Comment">*/</span>
        p-&gt;left = addtree(p-&gt;left, w);
    } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> 大きければ、右部分木へ </span><span class="Comment">*/</span>
        p-&gt;right = addtree(p-&gt;right, w);
    }
    <span class="Statement">return</span> p;
}

<span class="Comment">/*</span><span class="Comment"> treeprint : 木 p を順序立てて印字 </span><span class="Comment">*/</span>
<span class="Type">void</span> treeprint(<span class="Type">struct</span> tnode *p)
{
    <span class="Statement">if</span> (p != <span class="Constant">NULL</span>) {
        treeprint(p-&gt;left);
        printf(<span class="Constant">&quot;</span><span class="Special">%4d</span><span class="Constant"> </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, p-&gt;count, p-&gt;word);
        treeprint(p-&gt;right);
    }
}

<span class="Comment">/*</span><span class="Comment"> talloc : tnode をつくる </span><span class="Comment">*/</span>
<span class="Type">struct</span> tnode *talloc(<span class="Type">void</span>)
{
    <span class="Statement">return</span> (<span class="Type">struct</span> tnode *) malloc(<span class="Statement">sizeof</span>(<span class="Type">struct</span> tnode));
}

<span class="Comment">/*</span><span class="Comment"> my_strdup : s の複製をつくる </span><span class="Comment">*/</span>
<span class="Type">char</span> *my_strdup(<span class="Type">char</span> *s)
{
    <span class="Type">char</span> *p;

    p = (<span class="Type">char</span> *) malloc(strlen(s)+<span class="Constant">1</span>); <span class="Comment">/*</span><span class="Comment"> +1 for '\0' </span><span class="Comment">*/</span>
    <span class="Statement">if</span> (p != <span class="Constant">NULL</span>) {
        strcpy(p, s);
    }
    <span class="Statement">return</span> p;
}

<span class="Comment">/*</span><span class="Comment"> tnode を freq へコピーする </span><span class="Comment">*/</span>
<span class="Type">struct</span> freq *
tnode_cp_to_freq(<span class="Type">struct</span> tnode *p, <span class="Type">struct</span> freq *f)
{
    <span class="Statement">if</span> (p != <span class="Constant">NULL</span>) {
        tnode_cp_to_freq(p-&gt;left, f);
        f = word_cp_to_freq(p, f);
        tnode_cp_to_freq(p-&gt;right, f);
    }
    <span class="Statement">return</span> f;
}

<span class="Comment">/*</span><span class="Comment"> word を f に追加する </span><span class="Comment">*/</span>
<span class="Type">struct</span> freq *
word_cp_to_freq(<span class="Type">struct</span> tnode *p, <span class="Type">struct</span> freq *f)
{
    <span class="Statement">if</span> (f == <span class="Constant">NULL</span>) { <span class="Comment">/*</span><span class="Comment"> 新しい単語がきた </span><span class="Comment">*/</span>
        f = falloc();
        f-&gt;word[<span class="Constant">0</span>] = p-&gt;word;
        f-&gt;word_count = <span class="Constant">1</span>;
        f-&gt;count = p-&gt;count;
        f-&gt;left = f-&gt;right = <span class="Constant">NULL</span>;
    } <span class="Statement">else</span> <span class="Statement">if</span> (f-&gt;count == p-&gt;count) { <span class="Comment">/*</span><span class="Comment"> 等しければ、単語を追加 </span><span class="Comment">*/</span>
        f-&gt;word[f-&gt;word_count] = p-&gt;word;
        f-&gt;word_count++;
    } <span class="Statement">else</span> <span class="Statement">if</span> (f-&gt;count &lt; p-&gt;count) { <span class="Comment">/*</span><span class="Comment"> 小さければ、左部分木へ </span><span class="Comment">*/</span>
        f-&gt;left = word_cp_to_freq(p, f-&gt;left);
    } <span class="Statement">else</span> { <span class="Comment">/*</span><span class="Comment"> 大きければ、右部分木へ </span><span class="Comment">*/</span>
        f-&gt;right = word_cp_to_freq(p, f-&gt;right);
    }
    <span class="Statement">return</span> f;
}

<span class="Type">void</span> freqprint(<span class="Type">struct</span> freq *f)
{
    <span class="Type">int</span> i;

    <span class="Statement">if</span> (f != <span class="Constant">NULL</span>) {
        freqprint(f-&gt;left);
        printf(<span class="Constant">&quot;</span><span class="Special">%4d</span><span class="Constant">&quot;</span>, f-&gt;count);
        <span class="Statement">for</span> (i=<span class="Constant">0</span>; i&lt;f-&gt;word_count; i++) {
            printf(<span class="Constant">&quot; </span><span class="Special">%s</span><span class="Constant">&quot;</span>, f-&gt;word[i]);
        }
        printf(<span class="Constant">&quot;</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
        freqprint(f-&gt;right);
    }
}

<span class="Comment">/*</span><span class="Comment"> falloc : freq をつくる </span><span class="Comment">*/</span>
<span class="Type">struct</span> freq *falloc(<span class="Type">void</span>)
{
    <span class="Statement">return</span> (<span class="Type">struct</span> freq *) malloc(<span class="Statement">sizeof</span>(<span class="Type">struct</span> freq));
}

<span class="Comment">/*</span><span class="Comment"> getword : 入力から次の語または文字を求める </span><span class="Comment">*/</span>
<span class="Type">int</span> getword(<span class="Type">char</span> *word, <span class="Type">int</span> lim)
{
    <span class="Type">int</span> c, getch(<span class="Type">void</span>);
    <span class="Type">void</span> ungetch(<span class="Type">int</span>);
    <span class="Type">char</span> *w = word;

    <span class="Statement">while</span> (isspace(c = getch()))
        ;
    <span class="Statement">if</span> (c != <span class="Constant">EOF</span>) {
        *w++ = c;
    }
    <span class="Statement">if</span> (!isalpha(c)) {
        *w = <span class="Special">'\0'</span>;
        <span class="Statement">return</span> c;
    }
    <span class="Statement">for</span> ( ; --lim &gt; <span class="Constant">0</span>; w++) {
        <span class="Statement">if</span> (!isalnum(*w = getch())) {
            ungetch(*w);
            <span class="Statement">break</span>;
        }
    }
    *w = <span class="Special">'\0'</span>;
    <span class="Statement">return</span> word[<span class="Constant">0</span>];
}

<span class="Type">int</span> getch(<span class="Type">void</span>) <span class="Comment">/*</span><span class="Comment"> (押し戻された可能性もある) 1文字をとってくる </span><span class="Comment">*/</span>
{
    <span class="Statement">return</span> (bufp &gt; <span class="Constant">0</span>) ? buf[--bufp] : getchar();
}

<span class="Type">void</span> ungetch(<span class="Type">int</span> c) <span class="Comment">/*</span><span class="Comment"> 文字を入力に押し戻す </span><span class="Comment">*/</span>
{
    <span class="Statement">if</span> (bufp &gt; BUFSIZE)
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;ungetch : too many characters</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    <span class="Statement">else</span>
        buf[bufp++] = c;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4403/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Head First Rails 8章 『アクション「news」を作成する』 のルートについて</title>
		<link>http://www.serendip.ws/archives/4456</link>
		<comments>http://www.serendip.ws/archives/4456#comments</comments>
		<pubDate>Tue, 02 Mar 2010 07:49:24 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4456</guid>
		<description><![CDATA[O&#8217;Reilly の Head First Rails の8章 『アクション「news」を作成する』 (p345) で記述されているルートを設定して news.xml を表示させると、ActiveRecord::RecordNotFound in IncidentsController#show という風に show メソッドを実行しようとしてエラーとなってしまう。
調べてみると、このようなフォーラム &#34;Error with chapter 8 files &#8211; O&#8217;Reilly Forums&#34; があった。
config/routes.rb の最初の方にあ]]></description>
			<content:encoded><![CDATA[<p>O&#8217;Reilly の Head First Rails の8章 『アクション「news」を作成する』 (p345) で記述されているルートを設定して news.xml を表示させると、<code>ActiveRecord::RecordNotFound in IncidentsController#show</code> という風に <code>show</code> メソッドを実行しようとしてエラーとなってしまう。</p>
<p>調べてみると、このようなフォーラム &quot;<a href="http://forums.oreilly.com/content/Head-First-Rails/3135/Error-with-chapter-8-files/" class="out" rel="external">Error with chapter 8 files &#8211; O&#8217;Reilly Forums</a>&quot; があった。<br />
config/routes.rb の最初の方にある <code>map.resources :incidents</code> を追加したルートの後に記述するといいらしい。</p>
<pre><span class="Type">ActionController</span>::<span class="Type">Routing</span>::<span class="Type">Routes</span>.draw <span class="Statement">do</span> |<span class="Identifier">map</span>|
  <span class="Comment"># この設定を、追加するルートの後に記述するよう修正する</span>
  <span class="Comment"># map.resources :incidents</span>

  <span class="Comment">#...省略...#</span>

  <span class="Comment"># 追加するルート</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">/incidents/news</span><span class="Special">'</span>, <span class="Constant">:action</span>=&gt;<span class="Special">'</span><span class="Constant">news</span><span class="Special">'</span>, <span class="Constant">:controller</span>=&gt;<span class="Special">'</span><span class="Constant">incidents</span><span class="Special">'</span>, <span class="Constant">:format</span>=&gt;<span class="Special">'</span><span class="Constant">xml</span><span class="Special">'</span>
  <span class="Comment"># ここに記述する</span>
  map.<span class="Identifier">resources</span> <span class="Constant">:incidents</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">:controller/:action/:id</span><span class="Special">'</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">:controller/:action/:id.:format</span><span class="Special">'</span>
<span class="Statement">end</span>
</pre>
<p>ところが、この設定にしても <code>show</code> メソッドを実行しようとしてしまう。</p>
<p>さらに調べてみると、このような記事が、&quot;<a href="http://www.gnnk.net/20100207105824/" class="out" rel="external">www.gnnk.net &#8211; [Rails][本]Head First Rails</a>&quot;。</p>
<p>そこで、ルート設定のパスに .xml の拡張子を含む形で記述してみる。</p>
<pre><span class="Type">ActionController</span>::<span class="Type">Routing</span>::<span class="Type">Routes</span>.draw <span class="Statement">do</span> |<span class="Identifier">map</span>|
  <span class="Comment"># この設定を、追加するルートの後に記述するよう修正する</span>
  <span class="Comment"># map.resources :incidents</span>

  <span class="Comment">#...省略...#</span>

  <span class="Comment"># 追加するルート(news.xmlとする)</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">/incidents/news.xml</span><span class="Special">'</span>, <span class="Constant">:action</span>=&gt;<span class="Special">'</span><span class="Constant">news</span><span class="Special">'</span>, <span class="Constant">:controller</span>=&gt;<span class="Special">'</span><span class="Constant">incidents</span><span class="Special">'</span>, <span class="Constant">:format</span>=&gt;<span class="Special">'</span><span class="Constant">xml</span><span class="Special">'</span>
  <span class="Comment"># ここに記述する</span>
  map.<span class="Identifier">resources</span> <span class="Constant">:incidents</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">:controller/:action/:id</span><span class="Special">'</span>
  map.<span class="Identifier">connect</span> <span class="Special">'</span><span class="Constant">:controller/:action/:id.:format</span><span class="Special">'</span>
<span class="Statement">end</span>
</pre>
<p>すると、この2つの修正で news.xml が表示されるようになった。</p>
<p>使用している ruby, rails, gem のバージョンは以下のとおり。</p>
<pre>$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
$ rails -v
Rails 2.3.5
$ gem -v
1.3.4
</pre>
<p>それにしても、フォーラムでもコメントされてるけど、どうして <code>flight</code> の場合は問題なく動作して <code>incident</code> の場合はダメなんだろう&#8230;</p>
<p><ins datetime="2010-03-02T17:32:53+0900">追記：p353 の <code>auto_discovery_link_tag</code> ヘルパーによる RSS フィードの追加にも修正が必要だった。本文のコードではフィードの URI に .xml の拡張子が付かないので、以下のように <code>:format</code> を指定するコードを追加した。</ins></p>
<pre><span class="PreProc"></span><span class="Special">&lt;%=</span> <span class="Identifier">auto_discovery_link_tag</span>(<span class="Constant">:rss</span>, {<span class="Constant">:action</span>=&gt;<span class="Special">'</span><span class="Constant">news</span><span class="Special">'</span>, <span class="Constant">:format</span>=&gt;<span class="Special">'</span><span class="Constant">xml</span><span class="Special">'</span>}) <span class="Special">%&gt;</span>
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114381/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/510Z2FElqzL._SL160_.jpg" alt="Head First Rails ―頭とからだで覚えるRailsの基本" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114381/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Head First Rails ―頭とからだで覚えるRailsの基本</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4873114381/serendip7822-22/ref=nosim/" title="Head First Rails ―頭とからだで覚えるRailsの基本" target="_blank">amazlet</a> at 10.02.25</div>
</div>
<div class="amazlet-detail">David Griffiths <br />オライリージャパン <br />売り上げランキング: 45786</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873114381/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4456/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
