Reputation: 148
I was trying to get the maximum length of a string from an array of strings.
I wrote this code:
char a[100][100] = {"solol","a","1234567","123","1234"};
int max = -1;
for(int i=0;i<5;i++)
if(max<strlen(a[i]))
max=strlen(a[i]);
cout<<max;
The output it gives is -1. But when I initialize the value of max by 0 instead of 1, the code works fine. Why is it so?
Upvotes: 2
Views: 9720
Reputation: 21
I think this might work for you.
#include <algorithm>
const size_t ARRAYSIZE = 100;
char stringArray[ARRAYSIZE][100] = {"solol","a","1234567","123","1234"};
auto longerString = std::max_element(stringArray, stringArray + ARRAYSIZE - 1, [](const auto& s1, const auto& s2){
return strlen(s1) < strlen(s2);
});
size_t maxSize = strlen(longerString[0]);
This works for me, returns the longest char array, just do a strlen over the "first element" and youre done. For your example, it returns 7.
Hope it helps.
Upvotes: 0
Reputation: 12659
size_t
is the unsigned integer type.
From C++ Standard#4.6:
A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.15) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.
The value of max
is -1
which represent the maximum value that an unsigned integer type can hold. In the expression max<strlen(a[i])
, the value returned by strlen
will be promoted to unsigned int
and will be compared with the maximum value of the unsigned integer. Hence the condition max<strlen(a[i])
will never true
for the given input and the value of max
will not change.
The longest string in the array of strings a
is of length 7
. When you initialize the max
with 0
or 1
, the expression max<strlen(a[i])
evaluate to true
for any string whose length is greater than the value of max
. Hence you will get the expected output.
Upvotes: 2
Reputation: 19023
When evaluating expressions, the compiler breaks each expression down into individual subexpressions. The arithmetic operators require their operands to be of the same type. To ensure this, the compiler uses the following rules:
If an operand is an integer that is narrower than an int, it undergoes integral promotion (as described above) to int or unsigned int. If the operands still do not match, then the compiler finds the highest priority operand and implicitly converts the other operand to match. The priority of operands is as follows:
long double (highest) double float unsigned long long long long unsigned long long unsigned int int (lowest)
In your case on of operands has type int and another one type size_t
, so max
was promoted to type size_t
, and bit representation of -1 is the biggest possible size_t
.
You might also want to look in the following parts of the Standard [conv.prom], [conv.integral], [conv.rank].
Upvotes: 1
Reputation: 691
strlen
returns an unsigned int and when doing the comparison -1 gets promoted to a maximum value an unsigned can hold.
To fix the code, change the max
definition to unsigned int max = 0
Upvotes: 1
Reputation: 10348
The function strlen
returns an unsigned integral (i.e. size_t
) so when you compare it to max
which is signed, it gets promoted to unsigned and that -1
turns to something like 0xffffffff
(the actual value depends on your architecture/compiler) which is larger than any of those strings.
Change max
type to be size_t
and never compare unsigned with signed integrals.
Upvotes: 6