Suppose I have the following func and want to compare field as variable and value as value. How can I do it?
bool ReadFile::compareField(string field, string value)
{
if (field == "value")
}
If you're talking about C++, then the answer is: you can't. Variables are a compile-time thing; they don't exist at run-time.
If you want to access parameters as strings, then you might consider using e.g. a std::map:
class MyClass
{
private:
std::map<std::string, int> params;
public:
MyClass()
{
params["height"] = 165;
params["weight"] = 65;
params["legs"] = 2;
}
int getParam(const std::string &str) const
{
return params[str];
}
};
I changed the above func without map to the following func:
bool ReadFile::compareField( string * field, string value){
int i;
string fieldName = *field;
//converting to lower case
for (i = 0; i< strlen(value.c_str());i++)
value[i] = tolower(value[i]);
for (i = 0; i< strlen(fieldName.c_str());i++)
fieldName[i] = tolower(fieldName[i]);
/////
cout << fieldName << endl;
if (strstr(fieldName.c_str(),value.c_str()) != NULL){
return true;
}
return false;
}
At first i convert to lowercase and then search with strstr func, But here is a nice note that i use address of that variable instead of its name.
Related
I want to replace every single variables in a string with specified strings.
namespace math {
map<string,string> setVar;
string setVariable(string& str, const map<string,string>& variables) {
for(auto& m : variables) {
size_t pos;
while((pos=str.find(m.first)) != string::npos)
str.replace(pos,m.first.length(),"("+m.second+")");
}
return str;
}
bool isStillContainVariable(const string& str, const map<string,string>& variables) {
for(auto& m : variables)
return (str.find(m.first)!=string::npos) ? false : true;
return false;
}
vector<string> makeToken(string& str) {
if(setVar.size()!=0) {
str = setVariable(str,setVar);
str = isStillContainVariable(str,setVar) ?
setVariable(str,setVar) : str;
}
cout << str << endl;
vector<string> res;
..... //I tokenize the string
return res;
}
}
If I use the following code it reaplce the string correctly.
int main() {
string str = "-(-(x)+lg(y)+5+ln(z))";
math::setVar["x"] = "lg(pi*lg(y))";
math::setVar["y"] = "z";
math::setVar["z"] = "10";
auto res = math::makeToken(str);
return 0;
}
But if I use the following code, the solution is just (x), but the correct solution would be sin(pi)
string str = "z";
math::setVar["x"]="sin(y)";
math::setVar["y"]="pi";
math::setVar["z"]="x";
auto res = math::makeToken(str);
After the replace the string will not contain any kind of variables if the replace is correct.
I have complety no idea how to reaplce the string.
You need some kind of loop within makeToken:
while (isStillContainsVariables(...))
{ ... do the replacement ... }
I am programming my custom string class with multiple methods. The issue is that the comparison method does not work as I intend. Instead of doing nothing when the two char arrays differ, an if conditional still proceeds in my main function.
There are no errors given when I compile with g++. The code is syntactically correct, however logically faulty. I know this because I can give the compare method two char arrays which differ in content, and it will not matter whether they differ this way, as the main function will run the if conditional for "s8.compare(s7) == 1" regardless if the result in the compare method is not true.
I will post the entire code below. Any help is greatly appreciated.
string.h
class Str {
private:
char *value;
int length;
int capacity;
//Doubles the size of the string when called.
void growArray();
//If the two strings are uneven, get absolute value of difference in length.
int difference(int a, int b);
//Calculates the size of a character array, passed in as an argument
int getCharArrSize(const char *v);
public:
Str();
explicit Str(const char *STR);
void copy(Str s);
void concatenate(Str s);
bool compare(Str s);
void print();
};
//Str constructor
Str::Str() {
//Assign value, capacity, and length to any new Str object
value = new char[100];
capacity = 100;
length = 0;
}
//Pass STR object as a pointer to string object constructor
Str::Str(const char *STR) {
length = getCharArrSize(STR);
capacity = 100;
value = new char[capacity];
//Copy contents from STR to string object
for (int i = 0; i < length; i++)
value[i] = STR[i];
}
//Doubles the size of the string when called.
void Str::growArray() {
const char *tmp = value;
capacity *= 2;
value = new char[capacity];
for (int i = 0; i < length; i++)
value[i] = tmp[i];
}
//If the two strings are uneven, get absolute value of difference in length.
int Str::difference(int a, int b) {
int d = 0;
if (a > b) d = a - b;
else if (b > a) d = b - a;
return d;
}
//Calculates the size of a character array, passed in as an argument
int Str::getCharArrSize(const char *v) {
int c = 0;
while (v[c] != '\0') {
c++;
}
return c;
}
//Overwrites the data of the string array with the data contained in s
void Str::copy(Str s) {
//Check ability for empty string object to hold Str s contents
if (capacity > s.length) {
//Copy over each element until s length is reached
for (int i = 0; i < s.length ; i++)
value[i] = s.value[i];
//Set string object length to copy's size
length = getCharArrSize(value);
} else { growArray(); }
}
//Concatenate Str s onto string object
void Str::concatenate(Str s) {
//Check ability for string object to hold itself and concatenated chars
if (capacity > length + s.length) {
//Fill string object with s object until end of combined lengths if necessary
for (int i = 0; i < length + s.length; i++)
value[length + i] = s.value[i];
//Set length based on chars in concatenated string object
length = getCharArrSize(value);
} else { growArray(); }
}
//Compare each element in Str s against string for similarities
bool Str::compare(Str s) {
if (length == s.length) {
if (*value == *s.value) {
while ((*value != value[length]) && (*s.value != s.value[s.length])) {
value++;
s.value++;
}
return true;
} else return false;
} else {
difference(length, s.length);
}
}
//Print function
void Str::print() {
std::cout << value << std::endl;
}
main.cpp
#include"string.h"
int main() {
Str s1("Hello ");
Str s2("World");
Str s3(", my ");
Str s4("Name ");
Str s5("is ");
Str s6("Chad!");
Str s7;
s7.copy(s1);
s7.concatenate(s2);
s7.concatenate(s3);
s7.concatenate(s4);
s7.concatenate(s5);
s7.concatenate(s6);
s7.print();
std::cout << "\n\n";
Str s8("Hello World, My Name is Chad!");
if (s8.compare(s7) == 1) {
std::cout << "They Match!" << std::endl;
}
Str s9("I dont match....");
if (s9.compare(s8) == 0) {
std::cout << "I differ by " << s8.compare(s6) << " characters" << std::endl;
}
}
The above code returns a result that appears correct, however changing (s8.compare(s7) == 1) to something like (s8.compare(s5) == 1) returns 'They match!' when I am trying to check each individual element in the char arrays against one another, and only return true if they are the same length and each character matches in the arrays.
Your program has undefined behavior since Str::compare does not have a return statement in one of the branches.
bool Str::compare(Str s) {
if (length == s.length) {
...
} else {
// Missing return statement.
difference(length, s.length);
}
}
Perhaps you want to change that line to:
return (difference(length, s.length) == 0);
Your loop is running without a comparison. You compare the initial values in the char array and then loop through the rest without comparison. So you will return true every time the initial values are equal.
Below the loop runs after the same length is determined then every char is compared. If they are not equal then the function will return false. Otherwise the function will return true.
bool Str::compare(Str s) {
if (length == s.length) {
while ((*value != value[length]) && (*s.value != s.value[s.length])) {
if (*value == *s.value) {
value++;
s.value++;
} else {
return false;//will return false as soon as a comparison is false
}
}
return true;
} else {
difference(length, s.length);
}
}
You also need to return a boolean from the difference function. If you want to return ints from that function switch to a int return on the compare function and use 0 and 1s as their boolean counterparts.
I am implementing a String matching algorithm for a username database. My method takes an existing Username database and a new username that the person wants and it checks to see if the username is taken. if it is taken the method is supposed to return the username with a number that isn't taken in the database.
Example:
"Justin","Justin1", "Justin2", "Justin3"
Enter "Justin"
return: "Justin4" since Justin and Justin with the numbers 1 thru 3 are already taken.
I have already written this code in Java, and now I am writing it in C++ for practice. I have a few problems though:
How do you compare two strings? I have tried strcmp and a few others but I always get the error message: cannot convert std::string to const char* for argument 2.
how do you concatenate an int and a string? in java it was as simple as using the + operator.
In my main function, it says there is no matching function call for Username::NewMember(std::string, std::string). why does it not recognize newMember in main?
#include<iostream>
#include<string>
using namespace std;
class Username {
public:
string newMember(string existingNames, string newName){
bool found = false;
bool match = false;
string otherName = NULL;
for(int i = 0; i < sizeof(existingNames);i++){
if(strcmp(existingNames[i], newName) == 0){
found = true;
break;
}
}
if(found){
for(int x = 1; ; x++){
match = false;
for(int i = 0; i < sizeof(existingNames);i++){
if(strcmp(existingNames[i],(newName + x)) == 0){
match = true;
break;
}
}
if(!match){
otherName = newName + x;
break;
}
}
return otherName;
}
else return newName;
}
int main(){
string *userNames = new string[4];
userNames[0] = "Justin";
userNames[1] = "Justin1";
userNames[2] = "Justin2";
userNames[3] = "Justin3";
cout << newMember(userNames, "Justin") << endl;
delete[] userNames;
return 0;
}
}
Ok, there is some mistakes in your code :
If you want to compare two strings, simply use the operator== : string == string2
If you want to append an int to a string in C++ you can use streams :
#include <sstream>
std::ostringstream oss;
oss << "Justin" << 4;
std::cout << oss.str();
You are passing a string* to the function newMember but you prototype doesn't match that :
string *userNames = new string[4];
newMember(userNames, "Justin"); // Call
string newMember(string existingNames, string newName); // Protype
I think it should be : string newMember(string* existingNames, string newName); no ?
In the example, your main function is inside you class Username. It is not correct in C/C++. Unlike Java, the main function as to be in the global scope.
Finally you should use const-reference parameter because you don't need to modify the content of them and you need to copy them either :
string newMember(string* existingNames, const string& newName);
// ^^^^^ ^
Are you sure you need something allocated dynamically in the main function ?
I want to pass iterator of a vector of pointers to a function. I am not sure how to pass it.
Is this the right way of doing it:
main() {
vector<MyObject*>::iterator it;
for (it = added.begin(); it < added.end(); it++) {
string value = DoSomething(it)
}
}
string DoSomething(MyObject* a)
{
if (a->isValid())
Str = "0";
..
..
return str;
}
The line:
string value = DoSomething(it)
should be:
string value = DoSomething(*it);
I want to pass iterator of a vector of pointers to a function.
string value = DoSomething(it);
You're trying to pass it correctly, but the function isn't written to use an iterator:
string DoSomething(MyObject* a)
This function wants a pointer... you can give it that:
string value = DoSomething(*it);
Or you can change your DoSomething function:
string DoSomething(vector<MyObject*>::iterator i)
{
if ((*i)->isvalid())
...
}
If you really want to pass the iterator to the function, its parameter should also be an iterator:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
string DoSomething(vector<string*>::iterator a) {
string* entry = *a;
cout << *entry << endl;
return "blah";
}
int main() {
vector<string*> added;
string v1 = "v1";
string v2 = "v2";
added.push_back(&v1);
added.push_back(&v2);
vector<string*>::iterator it;
for (it = added.begin(); it < added.end(); it++) {
string value = DoSomething(it);
}
}
You can see it in action here.
I found a bug on the function below. When temp = 10. It will convert temp to string '01'. instead of string'10'. I can't tell why?
Is there any better to convert Num to Str? Thanks.
completed Num2Str() as this,
static bool Num2Str(string& s, const T& value)
{
int temp = static_cast<int>(value); // When temp = 10.
s.push_back(char('0' + temp % 10));
temp /= 10;
while(temp != 0)
{
s.push_back(char('0' + temp % 10));
temp /= 10;
}
if(s.size() == 0)
{
return false;
}
if(s.find_first_not_of("0123456789") != string::npos)
{
return false;
}
return true;
}
Use std::ostringstream to convert numbers to strings.
Don't use free static functions in C++; use unnamed namespaces instead.
#include<sstream>
#include<string>
namespace {
void f()
{
int value = 42;
std::ostringstream ss;
if( ss << value ) {
std::string s = ss.str();
} else {
// failure
}
}
}
For a solution in the flavour of the existing code (although I'd prefer the existing built int to string conversion):
template<class T>
static std::string Num2Str(const T& value)
{
std::string s;
int temp = static_cast<int>(value);
if (!temp)
{
s = "0";
return s;
}
while(temp != 0)
{
s.insert(0,1,(char('0' + temp % 10)));
temp /= 10;
}
return s;
}
Need to add support for negative values, range checking, etc.
My favorite is the recursive version (mostly in C) for flipping the digits to be in the correct order.
void u2str(string& s, unsigned value){
unsigned d = value % 10;
value /= 10;
if (value > 0 )
u2str(s,value);
s.push_back('0'+d);
}
For 0, you get "0", but in all other cases you don't get leading zeros. As shown it assumes string is more efficient at appending than inserting. However, if inserting is, then you don't need the recursive trick (eg Keith's answer).
You could also use boost::lexical_cast (see http://www.boost.org/doc/libs/1_46_1/libs/conversion/lexical_cast.htm)
For example:
void log_message(const std::string &);
void log_errno(int yoko)
{
log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
}