I'm trying to write a program that inputs a string (that is actually a sentence) and an array. The function should check if the values in the array are the lengths of each word in the string.
Example 1: This is an example. (The array should be: [4,2,2,7].
Example 2: Space... The final frontier... (The array should be: [5,3,5,8]).
I'm struggling with a few things:
- How do I check if the length of a word is equal to the value in the array without putting the lengths in another array?
- Why does my code register symbols like ('.','!'...) as words?
- Why is my
lengthofstring
always 0? Is myif-statement
wrong?
Here is what I have written so far.
int checklength(const char *str,int array[],int n)
{
int i,j=0,start=0,end,lengthofword,lengthofstring,isittrue=0;
while(*(str lengthofstring)!='\0')
{
lengthofstring ;
}
for(i=0;i<lengthofstring 1;i )
{
if((*(str i)>=32 && *(str i)<=64) || (*(str i)>=91 && *(str i)<=96) || (*(str i)>=123 && *(str i)<=126))
{
end=i;
lengthofword=end-start; //Why is my lengthofword 0 here?
//Here is what I tried for checking if value is in array:
j ;
while(j<n)
{
if(array[j]==lengthofword)
{
isittrue=1;
}
break;
}
}
start=i 1;
}
return isittrue;
}
CodePudding user response:
- You check one word at a time and exit when the first length test fails.
*(str i)>=32 && *(str i)<=64)
matches those symbols and you don't exclude it elsewhere.- You operate on uninitialized data which is undefined behavior.
Here is how I would write this:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int is_word_len(const char *str, size_t n) {
size_t i = 0;
for(; i < n; i )
if(!isalpha(str[i]))
return 0;
return !isalpha(str[i]);
}
int is_str_lens(const char *str, size_t n, size_t array[n]) {
// Consider adding checks along these lines:
// assert(str);
// assert(*str);
// assert(n);
// assert(array);
size_t offset = 0;
size_t i = 0;
for(; str[offset] && i < n; i ) {
while(str[offset] && !isalpha(str[offset])) offset ;
if(!is_word_len(&str[offset], array[i]))
return 0;
offset = array[i];
}
while(str[offset] && !isalpha(str[offset])) offset ;
return i == n && !str[offset];
}
int main() {
struct {
char *str;
size_t n;
size_t *array;
} tests[] = {
{ "This is an example.", 4, (size_t []) { 4, 2, 2, 7} },
{ "Space... The final frontier...", 4, (size_t []) { 5, 3, 5, 8 } },
{ "...Space... The final frontier...", 4, (size_t []) { 5, 3, 5, 8 } },
{ "Space...", 2, (size_t []) { 5, 2 } },
{ "Babies x", 1, (size_t []) { 6 } }
{ "This", 2, (size_t []) { 2, 2 } }
};
for(size_t i = 0; i < sizeof tests / sizeof *tests; i ) {
printf("%s: %d\n", tests[i].str, is_str_lens(tests[i].str, tests[i].n, tests[i].array));
}
}
and output:
This is an example.: 1
Space... The final frontier...: 1
...Space... The final frontier...: 1
Space...: 0
Babies x: 0
This: 0
If you don't want to use isalpha()
then re-implement along these lines:
int my_isalpha(int c) {
return
c >= 'A' && c <= 'Z' ||
c >= 'a' && c <= 'z';
}
CodePudding user response:
Your code is hard to read and too complicated. You have very handy standard functions which can help you with your task.
int checklength(const char *str, const size_t *array, const size_t n, const char *delim)
{
int isittrue = 1;
size_t cpos = 0;
char *token;
char *modifStr = malloc(strlen(str) 1);
if(modifStr)
{
strcpy(modifStr, str);
token = strtok(modifStr, delim);
while(token)
{
if(array[cpos] != strlen(token))
{
isittrue = 0;
break;
}
cpos ;
token = strtok(NULL, delim);
}
}
else return -1;
free(modifStr);
return isittrue && cpos == n;
}
int main(void)
{
printf("%d\n", checklength("This is an example.", (size_t[]){4,2,2,7}, 4, " ."));
printf("%d\n", checklength("Space... The final frontier...", (size_t[]){5,3,5,8}, 4, " ."));
}
https://godbolt.org/z/xnf6sK1cx
You can improve this function by adding parameter checks, checking if number of words is not larger than the number of elements of the array etc. But I have left it for you....