generated from kenryuS/report-temp
finished cls11
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
Binary file not shown.
+75
-1
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
\usepackage{tex/preamble}
|
\usepackage{tex/preamble}
|
||||||
\usepackage{tex/simple-title}
|
\usepackage{tex/simple-title}
|
||||||
|
\usepackage{here}
|
||||||
|
|
||||||
\reportauthor{柴田健琉}
|
\reportauthor{柴田健琉}
|
||||||
\reporttitle{情報処理2 - 前期第11回課題}
|
\reporttitle{情報処理2 - 前期第11回課題}
|
||||||
@@ -16,12 +17,85 @@
|
|||||||
この課題のプログラムは以下の環境での動作が確認されている:
|
この課題のプログラムは以下の環境での動作が確認されている:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item{OS: Arch Linux, Linux 6.18.37-1-lts x86\_64}
|
\item{OS: NixOS 26.05 Yarara, Linux 7.1.2 x86\_64}
|
||||||
\item{CC: GCC 15.2.0}
|
\item{CC: GCC 15.2.0}
|
||||||
\item{CFLAGS: \texttt{-g -O1 -Wall -Wpedantic}}
|
\item{CFLAGS: \texttt{-g -O1 -Wall -Wpedantic}}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
\section{課題 - 回文判定}
|
\section{課題 - 回文判定}
|
||||||
|
|
||||||
|
入力された英文文字列が回文になっているか判定する\texttt{kaibun}関数を作成する.
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={回文判定プログラム}]{./src/cls11/main.c}
|
||||||
|
|
||||||
|
\subsection{実行結果}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=12cm]{./assets/cls11.png}
|
||||||
|
\caption{回文判定プログラムの実行結果}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{処理の流れ}
|
||||||
|
|
||||||
|
\subsubsection{\texttt{my\_strlen}関数}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item{\texttt{str}に対しヌルポインタチェックを実施し, エラーであれば異常値を返却する}
|
||||||
|
\item{変数\texttt{i}を宣言し, 0で初期化する}
|
||||||
|
\item{文字へのポインタ\texttt{str}から\texttt{i}分ずれたアドレスを指す文字がヌル文字でない, かつ\texttt{i}が最大文字カウント\texttt{max\_len}以下であれば, \texttt{i}をインクリメントする}
|
||||||
|
\item{条件を満たすまで3を繰り返す}
|
||||||
|
\item{\texttt{i}を返却する}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsubsection{\texttt{to\_lower}関数}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item{\texttt{str}に対しヌルポインタチェックを実施し, エラーであればサブルーティーンを早期終了させる}
|
||||||
|
\item{カウンタ変数\texttt{i}を0から文字列の長さ\texttt{sz}まで3を繰り返す}
|
||||||
|
\item{文字型ポインタ\texttt{str}から\texttt{i}分ずれたアドレスを指す文字がASCIIの'A'以上, 'Z'以下であるならば, 十六進数値0x20を足し, ASCIIの'a'から'z'の範囲にある文字に変更する}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsubsection{\texttt{strip}関数}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item{\texttt{str}と\texttt{dest}に対しヌルポインタチェックを実施し, エラーであれば異常値を返却する}
|
||||||
|
\item{変更後の文字列の長さを格納する整数型変数\texttt{ret\_sz}を宣言・初期化する}
|
||||||
|
\item{カウンタ変数\texttt{i}を0から文字列の長さ\texttt{sz}まで4を繰り返す}
|
||||||
|
\item{文字型ポインタ\texttt{str}から\texttt{i}分ずれたアドレスを指す文字がASCIIの'a'以上, 'z'以下であるならば, \texttt{dest}文字列に該当文字を追加し, \texttt{ret\_sz}をインクリメントする}
|
||||||
|
\item{\texttt{dest}文字列の終端にヌル文字を追加する}
|
||||||
|
\item{\texttt{ret\_sz}を返却する}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsubsection{\texttt{kaibun}関数}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item{\texttt{str}に対しヌルポインタチェックを実施し, エラーであれば論理偽を返却する}
|
||||||
|
\item{カウンタ変数\texttt{i}を0から文字列の長さ\texttt{sz}の半分まで3を繰り返す}
|
||||||
|
\item{文字ポインタ\texttt{str}の始点と終点から中央に向って\texttt{i}分ずれたアドレスが指す値が一致しなかった場合に論理偽を返却する}
|
||||||
|
\item{\texttt{for}ループを抜けたら論理真を返却する}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsubsection{\texttt{main}関数}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item{\texttt{buff}と\texttt{processed\_str}の2つそれぞれに\texttt{BUFF\_SZ} + 1文字分のメモリを確保する}
|
||||||
|
\item{標準入力から最大\texttt{BUFF\_SZ}文字の1行を取得し, \texttt{buff}に格納する}
|
||||||
|
\item{2でのエラー処理を行う}
|
||||||
|
\item{文字列\texttt{buff}の長さを取得, エラー処理も行う}
|
||||||
|
\item{文字列\texttt{buff}を\texttt{to\_lower}関数と\texttt{strip}関数で加工, \texttt{processed\_str}に格納}
|
||||||
|
\item{\texttt{processed\_str}に対し\texttt{kaibun}関数を適用, 結果を\texttt{isPalindrome}に格納}
|
||||||
|
\item{標準出力に\texttt{isPalindrome}の値を出力する}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsection{書く際の難点}
|
||||||
|
|
||||||
|
Off by one errorで\texttt{kaibun}関数内のポインタ演算の処理が一発で通らず, 何回か修正・試行した.
|
||||||
|
|
||||||
|
\subsection{想定されるバグ}
|
||||||
|
|
||||||
|
多くの関数で文字列の長さを指定する必要があるが, この長さを間違えると意図しない動作が発生してしまう.
|
||||||
|
例えば, \texttt{kaibun}関数で1文字多く・少なく指定してしまったため, 回文であっても正常に判定されないという現象が考えられる.
|
||||||
|
|
||||||
|
しかし, ユーザ側では長さの指定はできないので, プログラマが責任をもって記述することになる.
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|||||||
+23
-17
@@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
#define BUFF_SZ 128
|
#define BUFF_SZ 128
|
||||||
|
|
||||||
// Lenght of string including null terminator
|
// Obtain the lenght of string
|
||||||
int my_strlen(char *str, int max_len) {
|
int my_strlen(char *str, int max_len) {
|
||||||
|
if (str == NULL) return -1;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (*(str + i) != '\0' && i < max_len)
|
while (*(str + i) != '\0' && i < max_len)
|
||||||
i++;
|
i++;
|
||||||
@@ -14,6 +16,8 @@ int my_strlen(char *str, int max_len) {
|
|||||||
|
|
||||||
// convert ASCII CAPITAL CASE ALPHABETS into lower case alphabets
|
// convert ASCII CAPITAL CASE ALPHABETS into lower case alphabets
|
||||||
void to_lower(char *str, int sz) {
|
void to_lower(char *str, int sz) {
|
||||||
|
if (str == NULL) return;
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
for (int i = 0; i < sz; i++) {
|
||||||
if (*(str + i) >= 'A' && *(str + i) <= 'Z') {
|
if (*(str + i) >= 'A' && *(str + i) <= 'Z') {
|
||||||
*(str + i) = *(str + i) + 0x20;
|
*(str + i) = *(str + i) + 0x20;
|
||||||
@@ -23,12 +27,12 @@ void to_lower(char *str, int sz) {
|
|||||||
|
|
||||||
// remove every non-alphabet letters from string
|
// remove every non-alphabet letters from string
|
||||||
int strip(char *str, char *dest, int sz) {
|
int strip(char *str, char *dest, int sz) {
|
||||||
int ret_sz = 0;
|
|
||||||
|
|
||||||
if (str == NULL || dest == NULL) {
|
if (str == NULL || dest == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ret_sz = 0;
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
for (int i = 0; i < sz; i++) {
|
||||||
if (*(str + i) >= 'a' && *(str + i) <= 'z') {
|
if (*(str + i) >= 'a' && *(str + i) <= 'z') {
|
||||||
*(dest + ret_sz) = *(str + i);
|
*(dest + ret_sz) = *(str + i);
|
||||||
@@ -43,6 +47,8 @@ int strip(char *str, char *dest, int sz) {
|
|||||||
|
|
||||||
// check if string is a palindrome
|
// check if string is a palindrome
|
||||||
bool kaibun(char *str, int sz) {
|
bool kaibun(char *str, int sz) {
|
||||||
|
if (str == NULL) return false;
|
||||||
|
|
||||||
for (int i = 0; i < (sz - 1)/2; i++) {
|
for (int i = 0; i < (sz - 1)/2; i++) {
|
||||||
if (*(str + i) != *(str + sz - i - 2)) {
|
if (*(str + i) != *(str + sz - i - 2)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -53,28 +59,28 @@ bool kaibun(char *str, int sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
char *b = (char*)malloc(sizeof(char) * (BUFF_SZ + 1)); // BUFF_SZ letters + null terminator
|
// BUFF_SZ letters + null terminator
|
||||||
char *t = (char*)malloc(sizeof(char) * (BUFF_SZ + 1));
|
char *buff = (char*)malloc(sizeof(char) * (BUFF_SZ + 1));
|
||||||
|
char *processed_str = (char*)malloc(sizeof(char) * (BUFF_SZ + 1));
|
||||||
|
|
||||||
printf("Input string: ");
|
printf("Input string: ");
|
||||||
char* res = fgets(b, BUFF_SZ, stdin);
|
char* res = fgets(buff, BUFF_SZ, stdin);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
printf("Error while reading from stdin\n");
|
printf("Error while reading from stdin\n");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = my_strlen(b, BUFF_SZ);
|
int len = my_strlen(buff, BUFF_SZ);
|
||||||
|
if (len == -1) {
|
||||||
|
printf("Error on retrival of string length.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
to_lower(buff, len);
|
||||||
|
len = strip(buff, processed_str, len);
|
||||||
|
|
||||||
printf("len: %d\n", len);
|
bool isPalindrome = kaibun(processed_str, len + 1);
|
||||||
|
|
||||||
to_lower(b, len);
|
|
||||||
len = strip(b, t, len);
|
|
||||||
|
|
||||||
printf("len: %d\n", len);
|
printf("isPalindrome: %s\n", isPalindrome ? "true" : "false");
|
||||||
|
|
||||||
bool isPalindrome = kaibun(t, len + 1);
|
|
||||||
|
|
||||||
printf("isPalindrome: %d\n", isPalindrome);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user