\documentclass[a4j,11pt]{jarticle} % ファイル先頭から\begin{document}までの内容(プレアンブル)については, % 教員からの指示がない限り, { } の中を書き換えるだけでよい. % ToDo: 提出要領に従って,適切な余白を設定する \usepackage[top=25truemm, bottom=30truemm, left=25truemm, right=25truemm]{geometry} % ToDo: 提出要領に従って,適切なタイトル・サブタイトルを設定する \title{プログラミング演習1レポート \\ 演習課題: 名簿管理プログラムの作成} % ToDo: 自分自身の氏名と学生番号に書き換える \author{氏名: 原 直 (HARA, Sunao) \\ 学生番号: 0941xxxx} % ToDo: 教員の指示に従って適切に書き換える \date{出題日: 20xx年xx月xx日 \\ 提出日: 20xx年xx月xx日 \\ 締切日: 20xx年xx月xx日 \\} % 注:最後の\\は不要に見えるが必要. % ToDo: 図を入れる場合,以下の1行を有効にする %\usepackage{graphicx} \begin{document} \maketitle % 以下の6行は提出用のレポートでは必ず消すこと \textbf{\small※執筆上の注意:本書は空想上の課題に対するレポートの 執筆例である.章の構成と書くべき内容の参考として提示するもの であるため,課題内容やプログラムの仕様などは, 実際の演習課題の指示に従って適切にまとめ直す必要がある. 途中まで文を書いて「・・・」によって省略している箇所があるが, これに穴埋めをすることで提出できるレポートになるわけではない. また,サンプルと同じ書き出しで文章を書く必要はない.} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{概要} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 以下の3行は提出用のレポートでは必ず消すこと \textbf{\small※執筆上の注意:概要は多すぎず少なすぎずが重要である. 特に,次の3点について,執筆者の取り組みの概略が読者(=教員)に 伝わるようにしよう.このレポートで取り組んだ (1) 課題の内容, (2) 実験等によって得られた結果,(3) 結果に対しておこなった考察.\\} 本演習では,外部からの入力データを計算機で扱える内部形式に変換して格納し, それらを操作する方法について学習する. 具体的には,標準入力から与えられる名簿のCSVデータをC言語の構造体の配列に格納し, それらをソートして表示するプログラムを作成する. 与えられたプログラムの基本仕様と要件,および,本レポートにおける実装の概要を以下に述べる. \begin{enumerate} \setlength{\parskip}{0mm}\setlength{\itemsep}{0mm}%この1行で箇条書きの行間を調整している \item 基本仕様 \begin{enumerate} \item 標準入力から「コード,氏名,生年月日,性別,出身,身長,体重」からなる コンマ区切り形式 (CSV 形式) の名簿データを受け付けて, それらをメモリ中に登録する機能を持つ.CSV形式の例を以下に示す. % 波括弧の内部 {...} だけ文字サイズ等を設定する書き方の例 % 以下の例はフォントサイズ:10pt 行送り:11pt {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} 0,Takahashi Kazuyuki,1977-04-27,3,Saitama,184,78 10,Honma Mitsuru,1972-08-25,2,Hokkaidou,180,78 11,Ogura Shinsuke,1976-07-23,0,Kanagawa,177,72 13,Shibata Kazuya,1968-03-16,0,Hyougo,176,75 : \end{verbatim} } \item 標準入力から\verb|%|で始まるコマンドを受け付けて, 登録してあるデータを表示したり整列したりする機能を持つ. 実装するコマンドを表\ref{tbl:commands}に示す. \end{enumerate} \item 要件 \begin{enumerate} \item 名簿データは配列などを用いて少なくとも$100$件のデータを登録できるようにする. 今回のプログラムでは,構造体\verb|struct person|の配列\verb|person_array[]|を宣言して, $100$件のデータを格納できるようにする. \item 名簿データは構造体\verb|struct person|および構造体\verb|struct date|を利用して, 構造を持ったデータとしてプログラム中に定義して利用する. 実装すべきデータ構造は表\ref{tbl:structure_person}である. 表中の$n$~bytesとは,$n$バイトの\verb|char|型配列を意味する. \end{enumerate} \end{enumerate} \begin{table}[t] % 表の位置は原則として t または b である.hやHは使わない. \centering % この1行はbegin~endの中を中央寄せにする,というコマンド \caption{実装するコマンド} \label{tbl:commands} \begin{tabular}{|l|l|l|} \hline コマンド & 解説 & パラメータ範囲\\ \hline \verb|%Sn| & CSV の\verb|n|番目の項目でソート & \verb|n|: 1--7\\ \hline \verb|%Pn| & CSV の\verb|n|番目を抜き出して表示 & \verb|n|: 0--99 (0は全て)\\ \hline \end{tabular} \end{table} \begin{table}[t] \centering % この1行はbegin~endの中を中央寄せにする,というコマンド \caption{名簿データ} \label{tbl:structure_person} \begin{tabular}{|l|l|l|l|l|l|l|} \hline コード & 氏名 & 生年月日 & 性別 & 出身 & 身長 & 体重\\ \hline $32$~bit整数 & $20$~bytes & \verb|struct date| & \verb|char| & $10$~bytes & $32$~bit整数 & $32$~bit整数\\ \hline \end{tabular} \end{table} また,本レポートでは以下の考察課題について考察をおこなった. \begin{enumerate} \setlength{\parskip}{2pt}\setlength{\itemsep}{2pt}%この1行で箇条書きの行間を調整している \item 不足機能についての考察をおこなった.特に,・・・(サンプルのため省略) \item エラー処理についての考察をおこなった.例えば,・・・(サンプルのため省略) \item 構造体 \verb|struct profile| がメモリ中を占めるバイト数について確認をおこなった.    具体的には,\verb|sizeof|演算子を使用して・・・(サンプルのため中略)・・・確認をおこなった. \end{enumerate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{プログラムの作成方針} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 以下の3行は提出用のレポートでは必ず消すこと \textbf{\small ※執筆上の注意:講義中の説明などに基づいて計画した作成方針についてまとめる. 例えば,どういう手順で作成をおこなったのか?作成にあたって何を重視したのか? なお,コーディング中に考え直した細かい内容は,できる限り, この章ではなく後の「作成過程における考察」でまとめること.\\} プログラムをおおよそ以下の部分から構成することにした. それぞれについて作成方針を立てる. \begin{enumerate} \setlength{\parskip}{2pt} \setlength{\itemsep}{2pt} \item 必要なデータ構造の宣言部(\ref{sec:declare}節) \item 標準入力から得た CSV データの解析部(・・・節) \item 構文解析したデータの内部形式への変換部(・・・節) \item 各種コマンド実現部(・・・節) \end{enumerate} %--------------------------------------------------------------% \subsection{宣言部} \label{sec:declare} %--------------------------------------------------------------% ``宣言部''は・・・をする部分である. このレポートでは概要で示した表\ref{tbl:structure_person}に基づいて, 以下のように宣言する. {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} struct date { int y; int m; int d; }; struct person { int code; char name[20]; struct date bday; char type; char home[10]; int height; int weight; }; struct person person_array[100]; \end{verbatim} } ここで,・・・については・・・としている. これによって,・・・とすることができる. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{解析部} \label{sec:parse} %--------------------------------------------------------------% ``解析部''は・・・をおこなう箇所である. しかし,このままでは,・・・であるため,・・・である. そこで,段階的詳細化の考え方に基づいてさらなる詳細化をおこない, 下記の(a)から(e)のように分割することにする. \begin{enumerate} \setlength{\parskip}{2pt} \setlength{\itemsep}{2pt} \renewcommand{\labelenumi}{(\alph{enumi})} % この1行はリスト見出しを(a), (b)に変えるためのコマンド \item 標準入力から読むべき行が残っている間,文字の配列\verb|char line[]|に1行分を読み込む. \item \verb|line|の1文字目が,\verb|'%'|ならば,2文字目をコマンド名,3文字目以降をその引数として,決定されたコマンドを実行する. \item さもなくば\verb|line|をCSVとみなし\verb|','|を区切りとして7つの文字列に分割する. \item 分割してできた7つの文字列を変換部に渡し構造体に代入する. \item 次の行を読み込む \end{enumerate} ここで,・・・は・・・と詳細化することもできるが,今回は・・・とする. また,・・・で扱う文字列は・・・として処理するため,解析部に続く・・・では・・・に注意する必要がある. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{変換部} %--------------------------------------------------------------% ``変換部''は分割されたCSVデータを項目毎に型変換し, 対応する構造体メンバーに代入する部分である. メンバーとして様々な型を用いているため,適切な代入の使い分けが必要となる. 文字列は関数\verb|xxxxxx|を用いて代入する. 数値の場合,関数\verb|xxxx|を用いて文字列を・・・してから代入する. 構造体\verb|struct date|であるメンバー\verb|bday|については・・・してから代入する. なお,構造体への代入については,・・・を用いることで容易に実装することができる. 例えば,\verb|"2014-10-25"|のような文字列を・・・し, ・・・によって・・・しつつ格納するという処理は,・・・を・・・する処理と同じ処理である. 従って,区切り文字がCSVの\verb|','|とは異なる・・・になること以外は同様に記述できるはずである. また,解析部から与えられた文字列は揮発性であることにも注意する. つまり,変換部で文字列を処理する際には・・・を・・・するのではなく, 関数・・・を使って・・・を行わなければならないことに気をつける必要がある. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{各種コマンド実現部} %--------------------------------------------------------------% ``各種コマンド実現部''は・・・の実際の処理をおこなう部分である. このレポートでは,具体的には・・・を実装している. 表示(\verb|%Pn|)は\verb|printf|で各項目毎に表示すればよい. ただし,・・・であることに注意が必要である. また,実装中に・・・ということがわかったため, ・・・のように実装をすることにしている. この実装に関する方針決定の詳細は後のxxxx節で説明する. ソートは,C の標準関数である \verb|qsort()| を使用することにする. 構造体の各メンバー毎にソートをするために,7つの比較関数を用意する. 7つの比較関数へのポインタを要素とする配列を宣言することによって 項目毎のソートを見通しよく行えるようにする. (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{プログラムおよびその説明} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 以下の4行は提出用のレポートでは必ず消すこと \textbf{\small ※執筆上の注意:変数や数値は$\backslash$verbや\$\$ で囲って,適切な書体で記述することを忘れずに. なお,このサンプルでは``わざと''一部の処理を省略している. 見た目の違いを確認して,自分のレポートでは処理を忘れないようにしよう.\\} プログラムリストは・・・節に添付している.プログラムは全部で267行からなる. 以下では,前節の作成方針における分類に基づいて,プログラムの主な構造について説明する. %--------------------------------------------------------------% \subsection{汎用的な関数の宣言(11行目から44行目)} %--------------------------------------------------------------% まず,汎用的な文字列操作関数として, \verb|subst()|関数を11--25行目で宣言し, % この行は適切な例 split()関数を27-44行目で宣言している. % この行は不適切な例 \verb|subst| は,\verb|sp|が指す文字列中の\verb|c1|文字を\verb|c2|に置き換える. プログラム中では,入力文字列中の末尾に付く 改行文字をヌル文字で置き換えるために使用している. split は str が指す文字列を区切文字 c で分割し, 分割した各々の文字列を指す複数のポインタからなる配列を返す関数である. プログラム中では,CSVを\verb|','|で分割し, 分割後の各文字列を返すのに使用されている. また,``2004-05-10'' のような日付を表す文字列を `-' で分割して, struct date を生成する際にも使用している. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{・・・部(93行目から214行目)} %--------------------------------------------------------------% 46--91行目は struct date データ型の宣言部とそれを扱う関数群である. 93--214行目は struct person データ型の宣言部とそれを扱う関数群である. 文字列から各データ型への変換を担う関数は, 名前を new\_データ型 とすることで, 変換部であることを明確にした. また,各種コマンド実現部の qsort に必要な比較関数群は,cmp\_メンバー名 という 名前に統一することで,比較関数であることを明確にした. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{・・・部(216行目から245行目)} %--------------------------------------------------------------% 216--245行目は,\%P, \%S のコマンドを解釈して 適切な関数を呼び出す部分である. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{・・・部(247行目から267行目)} %--------------------------------------------------------------% 247行目以降は,\verb|main()|関数であり, 作成方針で説明した解析部の動作におおよそ相当する. ただし (c) の 7つの文字列に分割する部分は,解析部の\verb|main()|関数では実現せず, 変換部である\verb|new_person()|関数中で\verb|split|を呼出すことにしている. この理由については,考察にて後述する. (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{プログラムの使用法} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 提出するレポートでは以下4行は必ず消すこと \textbf{\small ※執筆上の注意:この節はプログラムの使用法を説明す る節である.最低限,起動の方法,入力の形式と方法,出力の読み方 を入れること.当然,実装したコマンドすべてを説明すべきであるが, このサンプルのように説明に使う実行例が1つである必要はない.\\} 本プログラムは名簿データを管理するためのプログラムである. CSV形式のデータと \% で始まるコマンドを標準入力から受け付け, 処理結果を標準出力に出力する. 入力形式の詳細については,概要の節を参照のこと. プログラムは,Red Hat Linux 3.2.2-5 で動作を確認しているが, 一般的な UNIX で動作することを意図している. \verb|gcc|でコンパイルした後,標準入力から入力ファイルを与える. {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} % gcc -o program1 program1.c % ./program1 < csvdata.csv \end{verbatim} } プログラムの出力結果としてはCSVデータの各項目を読みやすい形式で出力する. 例えば,下記の cvsdata.csv に対して, {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} 0,Takahashi Kazuyuki,1977-04-27,3,Saitama,184,78 10,Honma Mitsuru,1972-08-25,2,Hokkaidou,180,78 %S3 %P0 \end{verbatim} } \noindent % noindentとはここでは段落を変えない(一字下げをしない)というコマンド. 以下のような出力を得る. {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} code: 10 name: Honma Mitsuru bday: 1972/08/25 type: 2 home: Hokkaidou height: 180 weight: 78 code: 0 name: Takahashi Kazuyuki bday: 1977/04/27 type: 3 home: Saitama height: 184 weight: 78 \end{verbatim} } \noindent 入力中の \%S3 は,これまでの入力データを 3番目の項目 (生年月日) でソートすることを示し, \%P0 は 入力した項目の全ての項目 ($1$--$7$) を表示することを 示している. (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{作成過程における考察} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %以下の3行は提出レポートでは不要なため消すこと. \textbf{\small ※執筆上の注意:ここでは,作成中に試行錯誤した内容, 例えば,「Aという実装ではなくBという実装にしたのはなぜか?」 などについて,バランスよくまとめる.\\} ・・・節で述べた実装方針に基づいて,・・・節ではその実装をおこなった. しかし,実装にあたっては実装方針の再検討が必要になる場合があった. 本節では,名簿管理プログラムの作成過程において検討した内容, および,考察した内容について述べる. %--------------------------------------------------------------% \subsection{・・・についての考察} %--------------------------------------------------------------% ・・・については方針通りに実装することができたが, ・・・については・・・となった. これは・・・に原因があると考えている. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{・・・についての考察} %--------------------------------------------------------------% ・・・の作成方針として・・・としたため,・・・となっていることには注意が必要である. なぜなら,・・・.しかし,・・・であるため,・・・である. 例えば,・・・としたいのであれば,・・・・とすればよい. (※サンプルのため省略) %--------------------------------------------------------------% \subsection{・・・についての考察} %--------------------------------------------------------------% ・・・については・・・という方針にしたが,・・・という方針にすることも考えられる. 今回は・・・ということを考えたため,・・・とすることにした. ただし,もし・・・であるならば,・・・は・・・よりも・・・であるから, ・・・という実装方針とするほうがよいだろう. (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{結果に関する考察} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %以下の5行は提出レポートでは不要なため消すこと. \textbf{\small ※執筆上の注意:考察課題を中心にまとめる. 自分で考えた考察課題を書くことも強く推奨しているが, 「作成過程における考察」とは区別して書くこと. 「作成されたプログラムから考察できること」を求めている. また,単なる感想で終わるような内容を書いてはいけない.\\} 演習課題のプログラムについて仕様と要件をいずれも満たしていることを プログラムの説明および使用法における実行結果例によって示した. ここでは,概要で挙げた以下の項目について考察を述べる. \begin{enumerate} \setlength{\parskip}{2pt} \setlength{\itemsep}{2pt} \item 不足機能についての考察 \item エラー処理についての考察 \item 構造体 \verb|struct person| のサイズに関する考察 \end{enumerate} %--------------------------------------------------------------% \subsection{不足機能についての考察} %--------------------------------------------------------------% (※サンプルのため省略) %--------------------------------------------------------------% \subsection{エラー処理についての考察} %--------------------------------------------------------------% (※サンプルのため中略) \subsubsection{CSVデータ処理中のエラー処理} CSVデータ中に,不正なデータが含まれていた場合の処理について考察する. エラーが含まれていた場合は,以下のような対処が考えられる. \begin{description} % descriptionで見出し後に開業するときは ~\\ とする. \item[(1) エラーのあった行を指摘して,無視する]~\\ この方法は,一回の入力で,できるだけ多くの エラーを発見できるため,通常はこの方法が好ましい. しかし,エラーのあった状態からの復帰を行う必要があるため プログラムが複雑になる. \item[(2) エラーのあった行を指摘して,終了する]~\\ この方法は,入力中に 1つのエラーを発見することしかできない. しかし,エラーのあった入力をデータを無視してしまうと 以降のデータ入力の正当性チェックにも影響がでるような場合には, この方法を採らざるを得ないこともある. \end{description} エラーのあった行を指摘せず,終了または無視するという 方法も考えられるが,正常終了との区別が付かないため実用的でない. 今回は,エラーのあった行を指摘して,無視する方法がよいと考えた. 現時点ではエラー処理については未実装であるが, プログラム中でエラーチェックすべき部分に\verb|ToDo:|で始まるコメントを入れて 改版時の目印となるようにしている. また,エラーのあった行を指摘するためには,・・・ (※サンプルのため省略) \subsubsection{・・・関数におけるエラー処理} (※サンプルのため省略) \subsubsection{・・・} (※サンプルのため省略) %--------------------------------------------------------------% \subsection{\texttt{struct person}のサイズ} %--------------------------------------------------------------% 以下のプログラムを \verb|gcc| でコンパイルして実行して, \verb|sizeof(struct person) = 88| という結果を得た. (※サンプルのため省略) {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} 1 my_person_data: 2 .long 999 ← 4バイト code 3 .string "taro" ← 5バイト name (末尾のヌルを入れて) 4 .zero 25 ← name が 30 になるように 0 を埋める 5 .zero 2 ← **** 2バイトの調整用 padding 6 .long 2000 ← 4バイト date.y = 2000 7 .long 1 ← 4バイト date.m = 1 8 .long 1 ← 4バイト date.d = 1 9 .byte 0 ← 1バイト type 10 .string "Kagawa" ← 7バイト home (末尾のヌルを入れて) 11 .zero 23 ← home が 30 になるように 0 を埋める 12 .zero 1 ← **** 1バイトの調整用 padding 13 .long 180 ← 4バイト height = 180 14 .long 75 ← 4バイト weight = 75 \end{verbatim} } これを見ると,5行目と12行目に合計で 3バイトの padding が入っていることが分かる. よく見ると .long つまり int の前に必ず入って 4バイト境界に 整数が跨がらないようになっている. しかし,10行目の home のように,文字列の場合は, もともと 1バイト単位で処理することが 前提のためか,特に 4バイト境界に納めるような padding は行われていない. (つまり 9行目と10行目の間に .zero 3 が入らない) 家電の中に組込まれているマイコンなどの メモリが少ないマシンにおいては, 実行効率よりもこのメモリの無駄使いが問題になることがある. そのような場合に対応するため,gcc はこの padding を止める オプションを提供している. 同じコードを -fpack-struct オプションを付けてコンパイルすると, メモリを無駄に使用しない,以下のコードを生成する. {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} 1 my_person_data: 2 .long 999 3 .string "taro" 4 .zero 25 5 .long 2000 6 .long 1 7 .long 1 8 .byte 0 9 .string "Kagawa" 10 .zero 23 11 .long 180 12 .long 75 \end{verbatim} } (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{感想} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (※サンプルのため省略) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{作成したプログラム} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 作成したプログラムを以下に添付する. 与えられた課題については,・・・節で示したようにすべて正常に動作したことを付記しておく. % % 行番号付きのリストを挿入 % cat -n ds-sample.c > ds-sample.txt % としたものを貼付する. % なお, fold コマンドを使うと指定行数で折り返すことができる. % 詳しくは fold --help を実行してヘルプを読んでみるとよい. % {\fontsize{10pt}{11pt} \selectfont \begin{verbatim} 1 #include 2 #include 3 #include 4 5 #define MAX_LINE_LEN 256 6 7 /****************************************************************/ 8 /* string fuctions */ 9 /****************************************************************/ 10 11 /* substitute C1 to C2 in string SP. */ 12 /* return value: number of replacement */ 13 int subst(char *sp, char c1, char c2) 14 { 15 int n = 0; 16 17 while (*sp){ 18 if (*sp == c1){ 19 *sp = c2; 20 n++; 21 } 22 sp++; 23 } 24 return n; 25 } 26 27 /* split STR using delimiter char C */ 28 /* return value: number of split elements */ 29 /* ret[] points each split element */ 30 int split(char *str, char *ret[], char c, int max) 31 { 32 int cnt = 0; 33 34 ret[cnt++] = str; 35 36 while (*str && cnt < max){ 37 if (*str == c){ 38 *str = '\0'; 39 ret[cnt++] = str + 1; 40 } 41 str++; 42 } 43 return cnt; /* not more than MAX */ 44 } 45 (※サンプルのため中略) 264 } 265 } 266 return 0; 267 } \end{verbatim} } % 以下の3行は消すこと. \textbf{\small ※執筆上の注意:余白部分に文字がはみ出していないか,よく確認する. 例えば,\LaTeX によるコンパイル時のWarningメッセージを確認しよう. \texttt{Overfull hbox}が出ていたら,はみ出している場所があるはずである.} \end{document}