I used:
keep
for recording where is the begin of the word.
position_max
and position_min
for recording position of final char's word.
max
and min
for compare every word and find the length of longest and the smallest.
lenght
is the length of entire string.
#include<limits.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
#include<malloc.h>
int main(void)
{
char *stringa = "alex keep all money";
size_t x;
int keep;
int min;
int max;
int position_max;
int position_min;
int lenght;
keep = 1;
max = 0;
min = INT_MAX;
position_max = 0;
lenght = strlen(stringa);
while(x != lenght 1)
{
if(isalnum(stringa[x]) != 0)
{
keep = 1;
}
if(isspace(stringa[x]) != 0 || stringa[x] == '\0')
{
if(keep > max)
{
position_max = x;
max = keep;
}
if(keep < min)
{
position_min = x;
min = keep;
}
keep = 0;
}
x ;
}
puts("the longest word:");
for(x = position_max - max; x != position_max; x )
{
printf("%c",stringa[x]);
}
puts("\n\nthe smallest word:");
for(x = position_min - min; x != position_min; x )
{
printf("%c", stringa[x]);
}
return 0;
}
CodePudding user response:
as others already mentioned - you have problems with uninitialized variables (x
, position_min
), also there are couple edge cases missed: when you have spaces at the start/end or multiple consecutive ones, here is fixed version:
int main(void) {
const char * const stringa = " alex keep all money ";
size_t x = 0; // keep declaration and definition in one place, so it is easy to spot mistakes
unsigned int keep = 0;
unsigned int min = 0; // initial min/max should be zero to work properly later during printing
unsigned int max = 0;
size_t position_max = 0;
size_t position_min = 0;
const size_t length = strlen(stringa);
while (x <= length) {
if (x == length || isspace(stringa[x])) { // first cover end of string case
if (keep > 0) { // multiple spaces
if (max == 0 || keep > max) {
position_max = x;
max = keep;
}
if (min == 0 || keep < min) {
position_min = x;
min = keep;
}
keep = 0;
}
} else if (isalnum(stringa[x]))
keep ;
x ;
}
puts("the longest word:");
for(x = position_max - max; x < position_max; x ) printf("%c", stringa[x]);
puts("\n\nthe smallest word:");
for(x = position_min - min; x < position_min; x ) printf("%c", stringa[x]);
return 0;
}
CodePudding user response:
The program has undefined behavior at least because the variable x used in this while loop
while(x != lenght 1)
was not initialized
size_t x;
Another problem is the initial initializing of the variable keep
by 1
keep = 1;
This can results for example that for the string like "A BB" the substring with the maximum length will be "A"
instead of "BB"
provided that initially the variable x
was initialized by 0
Or if the string starts from space character ' '
like " A"
then the maximum substring will be " "
and using the expression x = position_max - max
in this for loop
for(x = position_max - max; x != position_max; x )
again results in undefined behavior.
Also you have to take into account situations when a string contains adjacent white spaces.
I would write a separate function for example as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
struct SubString
{
char *position;
size_t length;
};
struct MinMax
{
struct SubString min;
struct SubString max;
};
struct MinMax minmax_string( const char *s, const char *delim )
{
struct MinMax minmax =
{
.min = { .position = NULL, .length = 00 },
.max = { .position = NULL, .length = 0 }
};
for ( s = strspn( s, delim ); *s; s = strspn( s, delim ) )
{
const char *position = s;
s = strcspn( s, delim );
size_t length = s - position;
if ( minmax.min.position == NULL )
{
minmax.min.position = ( char * )position;
minmax.min.length = length;
minmax.max.position = ( char * )position;
minmax.max.length = length;
}
else if ( minmax.max.length < length )
{
minmax.max.position = ( char * )position;
minmax.max.length = length;
}
else if ( length < minmax.min.length )
{
minmax.min.position = ( char * )position;
minmax.min.length = length;
}
}
return minmax;
}
int main(void)
{
const char *s = "alex keep all money";
struct MinMax minmax = minmax_string( s, " \t" );
printf( "The minimal string is \"%.*s\" at position %zu\n",
( int )minmax.min.length, minmax.min.position, ( size_t )( minmax.min.position - s ) );
printf( "The maximum string is \"%.*s\" at position %zu\n",
( int )minmax.max.length, minmax.max.position, ( size_t )( minmax.max.position - s ) );
}
The program output is
The minimal string is "all" at position 10
The maximum string is "money" at position 14
If you want to use the standard C function isspace
then the function minmax_string
can look the following way
#include <stdio.h>
#include <ctype.h>
struct SubString
{
char *position;
size_t length;
};
struct MinMax
{
struct SubString min;
struct SubString max;
};
struct MinMax minmax_string( const char *s )
{
struct MinMax minmax =
{
.min = { .position = NULL, .length = 00 },
.max = { .position = NULL, .length = 0 }
};
do
{
while ( isspace( ( unsigned char )*s )) s;
if ( *s )
{
const char *position = s;
while ( *s && !isspace( ( unsigned char )*s ) ) s;
size_t length = s - position;
if ( minmax.min.position == NULL )
{
minmax.min.position = ( char * )position;
minmax.min.length = length;
minmax.max.position = ( char * )position;
minmax.max.length = length;
}
else if ( minmax.max.length < length )
{
minmax.max.position = ( char * )position;
minmax.max.length = length;
}
else if ( length < minmax.min.length )
{
minmax.min.position = ( char * )position;
minmax.min.length = length;
}
}
} while ( *s );
return minmax;
}
int main(void)
{
const char *s = "alex keep all money";
struct MinMax minmax = minmax_string( s );
printf( "The minimal string is \"%.*s\" at position %zu\n",
( int )minmax.min.length, minmax.min.position, ( size_t )( minmax.min.position - s ) );
printf( "The maximum string is \"%.*s\" at position %zu\n",
( int )minmax.max.length, minmax.max.position, ( size_t )( minmax.max.position - s ) );
}
The program output is the same as shown above that is
The minimal string is "all" at position 10
The maximum string is "money" at position 14
CodePudding user response:
Iterate through the string using a pair of pointers.
Use pointers to store the beginning of the longest and shortest words.
Use counters to store the lengths of the words. Updating longest and shortest as needed.
In case of duplicate lengths, this will use the first word found.
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
int main ( void) {
char *str = "compare every word, find the length of longest and the smallest";
char *begin = str;
char *end = str;
char *longest = str;
char *shortest = str;
int len = 0;
int longlen = 0;
int shortlen = INT_MAX;
printf ( "%s\n", str);
while ( *begin) {
while ( ! isalnum ( (unsigned char)*begin)) {
begin; //advance past non-alphanumeric
}
end = begin; //assign pointer to section to evaluate
len = 0;
while ( isalnum ( (unsigned char)*end)) {
end; //advance past alphanumeric
len; //count characters
}
printf ( "\tword '%.*s' length %d\n", len, begin, len);
if ( len > longlen) { //found longer word
longlen = len; //store length
longest = begin; //store pointer
}
if ( len && len < shortlen) { //found shorter word
shortlen = len; //store length
shortest = begin; //store pointer
}
begin = end; //assign pointer to iterate next section
}
printf ( "\nlength of longest word '%.*s' is %d\n", longlen, longest, longlen);
printf ( "length of shortest word '%.*s' is %d\n", shortlen, shortest, shortlen);
return 1;
}