所以我的问题是当我与修改后的字符串值进行比较,以及未修改的字符串值时,我没有得到 true 的预期结果,而是假即可。我已经重载了逻辑比较运算符,但这不是我想要做的,这无助于解决我的答案,但它确实有效,但是当我在 std :: map中使用它时它不起作用。
编辑:我需要知道的是std :: map用什么来通过它的迭代来逻辑地比较两个对象。
STRING.H
#pragma once
#include <iostream>
#include <string>
#include <vector>
enum Pos
{
BEGINNING,
ENDING
};
class String
{
public:
char *chars;
String();
String(char *chars);
String(const char *chars);
String(unsigned int size);
unsigned int Length();
String SubStr(unsigned int start, unsigned int end);
String SubStr(unsigned int start);
unsigned int HasStr(const char *chars);
unsigned int HasStrInv(const char *chars);
int FindFirst(const char *chars, Pos pos);
int FindLast(const char *chars, Pos pos);
std::vector<String> Split(const char *delimeter);
String operator+(const char *chars);
String operator=(const char *chars);
String operator+=(const char *chars);
bool operator==(const char *chars);
bool operator==(String str);
operator char*();
static bool Equals(const char *a, const char *b);
static unsigned int Length(const char *chars);
static String Concate(const char *a, const char *b);
};
String operator+(const char *a, String b);
bool operator==(const char *a, String b);
String.cpp
#include "String.h"
String::String()
: chars("")
{
}
String::String(char *chars)
{
this->chars = chars;
}
String::String(const char *chars)
{
this->chars = const_cast<char *>(chars);
}
String::String(unsigned int size)
{
chars = new char[size];
}
unsigned int String::Length()
{
return Length(chars);
}
String String::SubStr(unsigned int start, unsigned int end)
{
unsigned int size = ((++end) - start) + 1;
char *buffer = new char[size];
for (unsigned int i = start; i < end; i++)
{
buffer[i - start] = chars[i];
}
buffer[size - 1] = '\0';
return String(buffer);
}
String String::SubStr(unsigned int start)
{
unsigned int size = (Length() - start);
char *buffer = new char[size];
for (unsigned int i = start; i < Length(); i++)
{
buffer[i - start] = chars[i];
}
buffer[size] = '\0';
return String(buffer);
}
unsigned int String::HasStr(const char * chars)
{
unsigned int d = 0, count = 0;
for (unsigned int i = 0; i < strlen(this->chars); ++i)
{
if (this->chars[i] == chars[d])
{
++d;
if (d >= strlen(chars))
{
++count;
d = 0;
}
}
else
{
d = 0;
}
}
return count;
}
unsigned int String::HasStrInv(const char * chars)
{
bool greater = false;
unsigned int i, d = 0, start = 0, count = 0;
for (i = 0; i < Length(); ++i)
{
if (this->chars[i] == chars[d])
{
d++;
if (d >= strlen(chars))
{
if (greater)
{
greater = false;
++count;
}
start = i + 1;
d = 0;
}
}
else
{
greater = true;
d = 0;
}
}
if (start - 1 < Length() - 1)
{
++count;
}
return count;
}
int String::FindFirst(const char * chars, Pos pos)
{
unsigned int d = 0;
for (unsigned int i = 0; i < strlen(this->chars); ++i)
{
if (this->chars[i] == chars[d])
{
++d;
if (d >= strlen(chars))
{
switch (pos)
{
case Pos::BEGINNING:
return i - (strlen(chars) - 1);
break;
case Pos::ENDING:
return i;
break;
}
}
}
else
{
d = 0;
}
}
return -1;
}
int String::FindLast(const char * chars, Pos pos)
{
unsigned int d = strlen(chars) - 1;
for (unsigned int i = strlen(this->chars); i > 0; --i)
{
if (this->chars[i] == chars[d])
{
--d;
if (d >= strlen(chars))
{
switch (pos)
{
case Pos::BEGINNING:
return i;
case Pos::ENDING:
return i + (strlen(chars) - 1);
}
}
}
else
{
d = strlen(chars) - 1;
}
}
return -1;
}
std::vector<String> String::Split(const char *delimeter)
{
unsigned int size = HasStrInv(delimeter);
std::vector<String> buffer(size);
bool greater = false;
unsigned int i, d = 0, start = 0, count = 0;
for (i = 0; i < Length(); ++i)
{
if (this->chars[i] == delimeter[d])
{
d++;
if (d >= strlen(delimeter))
{
if (greater)
{
greater = false;
buffer[count++] = SubStr(start, i - strlen(delimeter));
}
start = i + 1;
d = 0;
}
}
else
{
greater = true;
d = 0;
}
}
if (start - 1 < Length() - 1)
{
buffer[count] = SubStr(start, Length() - 1);
}
return buffer;
}
String String::operator+(const char *chars)
{
return Concate(this->chars, chars);
}
String String::operator=(const char *chars)
{
this->chars = const_cast<char *>(chars);
return *this;
}
String String::operator+=(const char * chars)
{
this->chars = Concate(this->chars, chars);
return *this;
}
bool String::operator==(const char * chars)
{
return Equals(this->chars, chars);
}
bool String::operator==(String str)
{
return Equals(chars, str);
}
String::operator char*()
{
return chars;
}
bool String::Equals(const char *a, const char *b)
{
if (Length(a) == Length(b))
{
for (unsigned int i = 0; i < Length(a); ++i)
{
if (a[i] != b[i])
return false;
}
return true;
}
return false;
}
unsigned int String::Length(const char * chars)
{
unsigned int i = 0;
while (chars[i] != '\0')
{
++i;
}
return i;
}
String String::Concate(const char *a, const char *b)
{
unsigned int size = strlen(a) + strlen(b) + 1;
char *buffer = new char[size];
for (unsigned int i = 0; i < strlen(a); ++i)
{
buffer[i] = a[i];
}
for (unsigned int i = strlen(a); i < size - 1; ++i)
{
buffer[i] = b[i - strlen(a)];
}
buffer[size - 1] = '\0';
return String(buffer);
}
String operator+(const char *a, String b)
{
return String::Concate(a, b);
}
bool operator==(const char *a, String b)
{
return String::Equals(a, b);
}
修改示例
#include <iostream>
#include "String.h"
int main(int argc, char *argv[])
{
String s = "Textures/SpaceShip.png";
String a = s.SubStr(s.FindLast("/", Pos::ENDING) + 1);
if (a.chars == "SpaceShip.png")
{
std::cout << "Equals" << std::endl;
}
else
{
std::cout << "Not Equals" << std::endl;
}
return 0;
}
输出
Not Equals
未经修改的示例
#include <iostream>
#include "String.h"
int main(int argc, char *argv[])
{
String s = "Textures/SpaceShip.png";
String a = "Textures/SpaceShip.png";
if (s.chars == a.chars)
{
std::cout << "Equals" << std::endl;
}
else
{
std::cout << "Not Equals" << std::endl;
}
return 0;
}
输出
Equals
TextureManager.cpp
#include "TextureManager.h"
std::map<char *, Texture2D> TextureManager::textures;
Texture2D * TextureManager::GetTexture(String path)
{
auto it = textures.find(path);
if (it == textures.end())
throw new std::exception("LWE: Texture not found. " + path);
return &it->second;
}
void TextureManager::DeleteTexture(String path)
{
auto it = textures.find(path);
if (it == textures.end())
throw new std::exception("LWE: Texture not found. " + path);
glDeleteTextures(1, &it->second.id);
textures.erase(it);
}
void TextureManager::InsertTexture2D_PNG(String filePath)
{
Texture2D texture;
std::vector<unsigned char> data;
FileInfo fi = IOManager::ReadFile(filePath);
if (decodePNG(data, texture.width, texture.height, (unsigned char *)fi.data, fi.size, true) != 0)
throw new std::exception("Failed to decode png." + filePath);
glGenTextures(1, &texture.id);
glBindTexture(GL_TEXTURE_2D, texture.id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
textures.insert(std::make_pair(filePath.SubStr(filePath.FindLast("/", Pos::ENDING) + 1), texture));
}
答案 0 :(得分:1)
你不能使用(s.chars == a.chars)比较两个字符串,它比较两个指针的地址,并且它总是为两个不同的字符串对象返回false。
答案 1 :(得分:1)
std :: map不使用operator ==
它使用operator <
。您需要实现该运算符才能使用String
类型作为地图的键。
以下是一个示例 - 请注意参数的const
和函数 - 这是std::map
所必需的。在这种情况下,这意味着您还需要将Length
更改为const
:
bool String::operator < (const String &str) const
{
unsigned int myLength = Length();
unsigned int strLength = str.Length();
for (unsigned int i = 0; i < myLength && i < strLength; i++)
{
if (chars[i] < str.chars[i])
return true;
else if (chars[i] > str.chars[i])
return false;
}
if (myLength < strLength)
return true;
return false;
}
并使用它:
std::map<String, int> myMap;
myMap["abc"]++;
myMap["abc"]++;
myMap["def"]++;
for (auto & entry : myMap)
{
std::cout << entry.first.chars << ":" << entry.second << std::endl;
}