strlen()の自作
my_strlen.c
#include <stdlib.h> // size_t
#include <limits.h> // SIZE_MAX
#include <errno.h> // errno, EINVAL, EOVERFLOW
size_t my_strlen(const char *str)
{
if (str == NULL) {
errno = EINVAL;
return 0;
}
size_t len = 0;
while (str[len] != '\0') {
if (len == SIZE_MAX) {
errno = EOVERFLOW;
return 0;
}
len++;
}
return len;
}
strchr()の自作
my_strchr.c
#include <stdio.h> // NULL
char *my_strchr(const char *str, int chr)
{
// if (str == NULL)
// return NULL;
unsigned char target = (unsigned char)chr;
while (*str && (unsigned char)*str != target) {
str++;
}
if ((unsigned char)*str == target) {
return (char *)str;
}
return NULL;
}
strlen()とstrchr()を合わせたみたいな関数を作ってみました。
strnchrlen.c
#include <stdbool.h> //bool
#include <stdio.h> // ssize_t (#include <stdlib.h> でもOK)
#include <limits.h> // SSIZE_MAX
// #define NOT_FOUND (-1)
// #define NOT_LOOKED (-2)
// #define NULL_PTR (-3)
typedef enum errorType
{
NOT_FOUND = -1,
NOT_LOOKED = -2,
NULL_PTR = -3
} err_t;
bool chr_is_found_at(const char *str, ssize_t i, int chr)
{
if (str == NULL)
return false;
return ((unsigned char)str[i] == (unsigned char)chr);
}
ssize_t strnchrlen(const char *str, ssize_t n, int chr)
{
ssize_t len = 0;
if (str == NULL)
return NULL_PTR;
if (n < 1)
return NOT_LOOKED;
while (len < n) {
if (chr_is_found_at(str, len, chr))
return (len);
if (str[len] == '\0')
return NOT_FOUND;
len += 1;
}
return NOT_FOUND;
}
第2引数は文字列の中で見る文字数の最大値なので、特に指定がなければ、SSIZE_MAXを入れると楽だと思います。
第3引数を終端文字('\0')にすれば、普通のstrlen()と同様に使えます。
ssize_t len = strnchrlen(str, SSIZE_MAX, '\0');
strchr()を以下のように使うと、(最大値は異なりますが)同じような結果が得られます。
char *found = strchr(str, chr);
if (found)
size_t len = (size_t)(found - str);