-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathadvanced_string_handlers.c
182 lines (160 loc) · 4.27 KB
/
advanced_string_handlers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "shell.h"
/**
* _strtok - splits a string into words.
* @str: The string to split
* @delim: the delimeter to split on
*
* Return: a pointer to an array of strings (words) on success, NULL otherwise.
*/
char **_strtok(const char *str, const char *delim)
{
char **str_array;
int word_count, word_start, word_end; /* keeps track of words */
int len, index, i;
char *tmp_delim = (char *)delim;
if (delim == NULL)
tmp_delim = " \t\n"; /* assume spaces, tabs and newline */
word_count = get_word_count(str, tmp_delim);
if (word_count == 0)
return (NULL); /* no valid words */
str_array = malloc((word_count + 1) * sizeof(char *));
if (str_array == NULL)
return (NULL); /* memory allocation failed */
word_start = index = 0;
len = _strlen(str);
for (i = 0; i < len; i++)
{
if ((!_strchr(tmp_delim, str[i]) && _strchr(tmp_delim, str[i + 1])) ||
(!_strchr(tmp_delim, str[i]) && str[i + 1] == '\0'))
{
word_end = i + 1;
str_array[index] = new_word(str, word_start, word_end);
/* memory allocation for new word failed, clean up and leave */
if (str_array[index] == NULL)
return (free_str(&str_array), NULL);
index++;
}
else if (!_strchr(tmp_delim, str[i]) && !_strchr(tmp_delim, str[i + 1]))
continue; /* still in a word, keep counting */
else
word_start = i + 1;
}
/* terminate the array */
str_array[index] = NULL;
return (str_array);
}
/**
* _strpbrk - searches a string for any of a set of bytes
* @s: string
* @accept: substring
*
* Description: The _strpbrk() function locates the first occurrence in the
* string @s of any of the bytes in the string @accept.
*
* Return: A pointer to the byte in @s that matches one of the bytes in
* @accept, or NULL if no such byte is found.
*/
char *_strpbrk(const char *s, const char *accept)
{
int i, j;
for (i = 0; s[i] != '\0'; i++)
{
for (j = 0; accept[j]; j++)
{
if (s[i] == accept[j])
return ((char *)&s[i]); /* match found*/
}
}
return (NULL); /* no match found or end of string - return NULL */
}
/**
* _strspn - get length of a prefix substring
* @s: string
* @accept: substring
*
* Description: The _strspn() function calculates the length (in bytes) of the
* initial segment of @s which consists entirely of bytes in @accept.
*
* Return: The number of bytes in the initial segment of @s which
* consist only of bytes from @accept.
*/
size_t _strspn(const char *s, const char *accept)
{
size_t len = 0;
int i, map[256] = {0};
/* handle empty arguments */
if (s == NULL || accept == NULL)
return (0);
/* use a hash map for efficient lookup - assume ASCII */
for (i = 0; accept[i] != '\0'; i++)
map[(unsigned char)accept[i]] = 1;
for (i = 0; s[i] != '\0'; i++)
{
if (s[i] == SPACE) /* search till next word */
break;
else if (map[(unsigned char)s[i]])
len++; /* match found, increment length */
else
break; /* no match found */
}
return (len);
}
/**
* _strrchr - locate character in string (reverse)
* @s: the string
* @c: the character to search
*
* Description: The _strrchr() function returns a pointer to the last
* occurrence of the character @c in the string @s.
*
* Return: a pointer to the matched character or NULL if the character
* is not found
*/
char *_strrchr(const char *s, int c)
{
char *tmp_s = (char *)s;
size_t len = _strlen(tmp_s);
/* handle empty string */
if (s == NULL)
return (NULL);
while (tmp_s[--len] != '\0')
{
if (tmp_s[len] == c)
return (tmp_s + len); /* match found */
}
/* return a pointer to the null byte if 'c' is a null byte. */
if (c == '\0')
return (tmp_s);
return (NULL); /* no match found or end of string - return NULL */
}
/**
* get_word_count - Returns the number of words in a string.
* @str: string
* @delim: the delimeter to split on
*
* Return: Number of words
*/
int get_word_count(const char *str, const char *delim)
{
int in_word = 0; /* flag to track if we are in a word or not */
int word_count = 0;
char *tmp_delim = (char *)delim;
if (str == NULL || *str == '\0')
return (0);
if (delim == NULL)
tmp_delim = " \t";
while (*str)
{
if (_strchr(tmp_delim, *str))
{
in_word = 0; /* not in a word, reset flag */
}
else if (!in_word)
{
in_word = 1; /* found the start of a new word */
word_count++; /* count word */
}
str++;
}
return (word_count);
}