Muktadir Khan
Muktadir Khan

Reputation: 148

Longest string in an array of strings in C++

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

Answers (5)

Jonathan Michel
Jonathan Michel

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

H.S.
H.S.

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

Yola
Yola

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

nVxx
nVxx

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

imreal
imreal

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

Related Questions