String compare doesn't work??!!

Is there a reason why this IF statement never fires? The values are definitely the same.

Name is declared as a String in Struct Items. I have returned both Items*.Name* and Name outside the IF and the return is identical.
```
*String& NameValueCollection::Item(const String& Name)
{
 for (int i; i < Count; i++)
 {
   if(Items[i].Name == Name) //this never fires
   {
     return Items[i].Value;
     break;
   }
 }

return nullstring;
}*
```
Strange.

Strings are represented by pointers - you need to compare the actual string contents, not the pointer. For strings look up the strcmp() function.

I think you are comparing string references, not the String objects.
You may consider using the equals() method, which is supposed to work the same as ==.

Personally I'm a C guy and I would never mess with String myself. I'm strictly a char [] and strcmp() type dude.

MarkT:
Strings are represented by pointers - you need to compare the actual string contents, not the pointer. For strings look up the strcmp() function.

He's using String objects. Read this: String() - Arduino Reference
strcmp() isn't the right thing here.

Yah, his string objects are fine. The problem has got to be somewhere else.

For example, this simple example works fine

String Hello = "Hello";

int Test(const String& Name)
{
  return ( Hello == Name );
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println(Test("Hello"));  
}

void loop(void)
{
}

Prints '1' as expected.

I see no reason why that wouldn't work. The String class overrides the == operator doing exactly what your comparison thinks it should be doing.

There has to be something silly afoot... Case not exactly right? The right string not within the range of 0 to Count? I notice you don't specifically say "for (int i = 0; i < Count; i++)" Personally... I don't trust integers to start at 0. Is Count high enough?

Beakie:
Is there a reason why this IF statement never fires? The values are definitely the same.

Well, what is the value of "i" going into the loop. And "Count"? How is Items [ i ] .Name declared? There isn't enough information to say. What is your exact test data? When you say they are "the same" are there trailing spaces? Case differences?

 return Items[i].Value;

break;

You don't need to break after a return. Any code after a return is not executed.

for (int i; i < Count; i++)

I think I'm going with Nick - i is not initialised.

AWOL:

for (int i; i < Count; i++)

I think I'm going with Nick - i is not initialised.

I can't test this now but I don't think that's it. If I return Items[i].Name just before the if, it returns the first item in the array correctly.

I thought there might be trailing spaces so I changed the if to compare on length() and it returned a value... so it isn't that. It's a strange one.

but I don't think that's it.

But you are going to correct it, right?

AWOL:
But you are going to correct it, right?

Well, of course :slight_smile:

This fixed it?!?!?!?! It worked fine once I gave an initial value to i.

String& NameValueCollection::Item(const String& Name)
{
  for (int i = 0; i < Count; i++)
  {
    if(Items[i].Name == Name)
    {
      return Items[i].Value;
      break;
    }
  }

  return nullstring;
}

If I return the i-th value from the array without initialising i first, it gets me the 1st item.

String& NameValueCollection::Item(const String& Name)
{
  for (int i; i < Count; i++)
  {
    return Items[i].Name; //<<--this line
  }

  return nullstring;
}

Strange

Beakie:
This fixed it?!?!?!?! It worked fine once I gave an initial value to i.
...
Strange

What is strange about it? If you are looping with an undefined starting value the results are undefined.

If the value for i is 0 for one line, then surely it will be 0 for a different line if in the same point of the code?

Anyways. Works now.

Never mind the "anyway". I am hoping you will learn what the problem is. What do you mean by "a different line if in the same point of the code"? This line here:

 for (int i; i < Count; i++)

... which you initially had, the value "i" can be anything. Like, 42, for example. Or 32653. Or -100. So why on earth do you think that it will successfully process the items between (say) 6543 and "Count" if you don't start with a known value?

It worked fine once I gave an initial value to i.

Well, imagine that!
Assigning a value to an automatic made it work.
Will wonders never cease?

I am not suggesting it won't have weird results... I am questing why including the commented line would show i as 0 but if it is commented and runs the next line (if), it shows i as something else?

String& NameValueCollection::Item(const String& Name)
{
  for (int i; i < Count; i++)
  {
    //return Items[i].Name;
    if(Items[i].Name == Name)
    {
      return Items[i].Value;
    }
  }

  return nullstring;
}

The reason is that the value of i is 'undefined'. And 'undefined' can be anything anytime without ever having to explain itself or be predictable or anything. That's usually why we give values to our variables because we aren't much fond of 'undefined' behaviour.

AWOL:

It worked fine once I gave an initial value to i.

Well, imagine that!
Assigning a value to an automatic made it work.
Will wonders never cease?

Oscar Wilde once said, "Sarcasm is the lowest form of wit".

Beakie:
I am not suggesting it won't have weird results... I am questing why including the commented line would show i as 0 but if it is commented and runs the next line (if), it shows i as something else?

So you are asking why does code with undefined behaviour behave in a strange way? Because it is undefined? By definition you can't really explain it. But one possible explanation is that, due to the different amount of generated code, and the different registers that the compiler internally allocated, the value of i might just happen to be zero on this particular test case.