Having this code:
char a[20]="wasd", b[20]="asd";
if((a+1)==b)
printf("yes");
Will not return "yes", even if "a+1" is "asd". I am wondering what am I doing wrong?
You need to use strcmp to compare C strings. == will just compare the pointers.
For example:
#include <string.h> // or <cstring> if you're writing C++
...
char a[20]="wasd", b[20]="asd";
if(strcmp(a+1, b)==0)
printf("yes");
By the way, if you're writing C++, you'd be better off using std::string. Then you could have simply used == to compare them.
If it's not a student assignment and you truly are using C++(as your tag says) you should use strings. Now you're using arrays and comparing arrays addresses instead of real strings. In a C++ way your code might look like:
#include <iostream>
#include <string>
int main()
{
std::string a ="wasd";
std::string b ="asd";
if(a.substr(1) == b)
std::cout << "Yes!\n";
}
Well, there is a better way to find if one string contains another but the code is a direct mapping of your C code to the C++-ish one.
You are actually comparing pointer addresses, not the actual string contents.
Your code should use strcmp:
char a[20]="wasd", b[20]="asd";
if(strcmp(a+1, b) == 0)
printf("yes");
Be careful that strcmp returns 0 if the strings are identical.
A better and more idiomatic alternative would be to use std::string:
std::string a = "wasd", b = "asd";
if(a.substr(1) == b)
std::cout << "yes";
substr does copy the string though, so it is slightly less efficient than the previous approach.
You have to use strcmp from string.h to compare strings.
if(strcmp(a+1,b)==0)
in Your case.
As per your code, when using (a+1)==b you are comparing the addresses of the pointers pointing respectively to second character of string 'a' and the first character of string 'b'.
It can work if you modify your code as:
char a[20]="wasd", b[20]="asd";
if(*(a+1)==*b) // now we are comparing the values towards which the
printf("yes"); // respective pointers are pointing
You can also use compare() for comparison of strings included in .
Related
Screenshot 1
Here's my code.
#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
class Dragon
{
public:
char element[30];
int energy;
};
int main()
{
Dragon dragon;
char name[30];
cout<<"Enter element.\n\n";
cin>>name;
if(name=='Hell')
{
strcpy(dragon.element,"Hell Dragon");
dragon.energy=15000000;
}
else if(name=='Dark')
{
strcpy(dragon.element,"Dark Dragon");
dragon.energy=1000000;
}
else
cout<<"Unknown Dragon.";
cout<<"\nDragon's element = "<<dragon.element<<"\nDragon's energy level = "<<dragon.energy;
getch();
return 0;
}
Just tried this program on my own in C++ and have problems in fixing the following errors-
Errors and Warnings
If you do have an idea on how I can modify this, please help me out.
Thank you.
One cause of your issues is that == can't be used to compare contents of character arrays.
Solution 1: Use std::string
The std::string data type is the preferred data structure in C++ for text strings.
The std::string has overloaded == for comparing strings.
The std::string also has a find method for searching for a substring.
Solution 2: Use strcmp
The C language uses character arrays for strings. The C language also has str*() functions for processing character arrays.
The C++ language uses the str*() functions for processing the C-Style strings (character arrays).
Use strcmp to compare character arrays with string literals:
if (strcmp(name, "Hell") == 0)
You may also want to use strstr for finding substrings or strchr for finding characters in a character array (C-style string).
Hello I am trying to write a function that converts a string to lowercase by using a pointer instead of a return value.
void makeLowerCase(std::string* in){
//for loop tolower(char from *in);}
but I have no idea how to get each char out of my pointer to use tolower() with, or how to get how many chars are in the string as
*in.length()
and
sizeof(*in)/sizeof(char)
don't work for it. The former I get an error on the use of a pointer, the latter I get the same return value for sizeof(*in) so I don't even know how I would end my for loop.
C++ has a shortcut to get the member of an object pointed to by a pointer:
in->length()
For accessing characters, use parentheses:
(*in)[i]
Instead of passing by pointer and dealing with pointer syntax you can pass the string by reference and then you can use it just like a normal std::string. If you have to use a pointer then you can either use
in->length();
or
(*in).length();
The parentheses are required in the second case as . has a higher precedence then *.
As for transforming the string to lower case you can use the built in functions from <algorithm> and and that would give you
void makeLowerCase(std::string& in)
{
std::transform(in.begin(), in.end(), in.begin(), ::tolower);
}
*in.length()
does not work because . has a higher precedence than *. Use parantheses:
(*in).length()
sizeof(*in)/sizeof(char)
is the same as
sizeof(*in) / 1
because sizeof(char) == 1. sizeof(*in) == sizeof(std::string), so this yields the size of the std::string object itsself, not the string of characters, which is implemention-defined.
This information, in combination with iterators, for_each, and lambdas, make for a pretty three-liner without any functions:
#include <cctype>
...
for (char& c : str)
c = std::tolower(c);
Notes:
Use references instead. They look better and are easier usable. Pointers should only be used in C++ for low-level stuff or when there's no way to cut them out.
For pointers you would use the pointer operator. So that would be
in->length();
However a naked loop is not the ideal way (nor is using pointers to be honest).
A better way would be to use iterators to iterate through the string and convert it that way.
for (auto it=in->begin(); it!=in->end(); ++it) {
*it = std::tolower(*it);
}
Basically my task is having to sort a bunch of strings of variable length ignoring case. I understand there is a function strcasecmp() that compares cstrings, but doesn't work on strings. Right now I'm using getline() for strings so I can just read in the strings one line at a time. I add these to a vector of strings, then convert to cstrings for each call of strcasecmp(). Instead of having to convert each string to a cstring before comparing with strcasecmp(), I was wondering if there was a way I could use cin.getline() for cstrings without having a predefined char array size. Or, would the best solution be to just read in string, convert to cstring, store in vector, then sort?
I assume by "convert to cstring" you mean using the c_str() member of string. If that is the case, in most implementation that isn't really a conversion, it's just an accessor. The difference is only important if you are worried about performance (which it sounds like you are). Internally std::strings are (pretty much always, but technically do not have to be) represented as a "cstring". The class takes care of managing it's size for you, but it's just a dynamically allocated cstring underneath.
So, to directly answer: You have to specify the size of the array when using cin.getline. If you don't want to specify a size, then use getline and std::string. There's nothing wrong with that approach.
C++ is pretty efficient on its own. Unless you have a truly proven need to do otherwise, let it do its thing.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
bool cmp(string a, string b)
{
return(strcasecmp(a.c_str(), b.c_str()) < 0);
}
int main(int argc, char *argv[])
{
vector<string> strArr;
//too lazy to test with getline(cin, str);
strArr.push_back("aaaaa");
strArr.push_back("AAAAA");
strArr.push_back("ababab");
strArr.push_back("bababa");
strArr.push_back("abcabc");
strArr.push_back("cbacba");
strArr.push_back("AbCdEf");
strArr.push_back("aBcDeF");
strArr.push_back(" whatever");
sort(strArr.begin(), strArr.end(), cmp);
copy(strArr.begin(), strArr.end(), ostream_iterator<string>(cout, " \n"));
return(0);
}
I have a task to implement "void makeAmbigram(char*)" that will print on screen ambigram of latin string or return something like 'ambigram not possible'. Guess it's just about checking if string contains only of SNOXZHI and printing string backwards. Or am I wrong ?
I'm a complete noob when dealing with cpp so that's what I've created :
#include <iostream>
using namespace std;
char[]words;
char[]reversed;
char[] ret_str(char* s)
{
if(*s != '\0')
ret_str(s+1);
return s;
}
void makeAmbigram(char* c)
{
/* finding chars XIHNOZS and printing ambigram */
}
int main()
{
cin>>words;
reversed = ret_str(words);
makeAmbigram(reversed);
return 0;
}
I can reverse string but how to check if my reversed string contains only needed chars ?
I've found some function but it's hard or even imposible to implement it for greater amount of chars : www.java2s.com/Code/C/String/Findcharacterinstringhowtousestrchr.htm
You need to allocate space in your arrays or use std::vector. The arrays word and reversed are just pointers and no space is allocated. The C++ language does not support dynamic arrays; however, the STL provides std::vector which dynamically allocates space as required.
Change:
char[]words;
char[]reversed;
To:
#define MAX_LETTERS 64
char words[MAX_LETTERS + 1]; // + 1 for terminating nul character ('\0')
char reversed[MAX_LETTERS + 1];
Or:
#include <string>
std::string words;
std::string reversed;
Or:
#include <vector>
std::vector<char> words;
std::vector<char> reversed;
As far as the ambigram rules go, you need to talk to your instructor. Also, if this is homework, add a tag indicating so.
Hint: The std::string data type has some reverse iterators which may be of use to you.
std::string has an entire family of member functions along the lines of find_first_of. You can pass in a string containing all the letters your ambigram test requires, and they'll find whether any of those letters are present in the source string.
The complete list of string functions is available here.
As for the definition of ambigrams, given the wiki page you've included in the question...you need to check if a letter is legible if viewed upside down, for eg. u/n, w/m, d/p, q/b and so on. There are of course more complex rules was well, for eg. 'ui' can resemble 'm' if viewed upside down.
However, if you're only required to check if your string contains only SNOXZHI, you can look into a regular expression (regex) for the same, and compare input string character-wise to your regex.
I am very confused about when to use string (char) and when to use string pointers (char pointers) in C++. Here are two questions I'm having.
which one of the following two is correct?
string subString;
subString = anotherString.sub(9);
string *subString;
subString = &anotherString.sub(9);
which one of the following two is correct?
char doubleQuote = aString[9];
if (doubleQuote == "\"") {...}
char *doubleQuote = &aString[9];
if (doubleQuote == "\"") {...}
None of them are correct.
The member function sub does not exist for string, unless you are using another string class that is not std::string.
The second one of the first question subString = &anotherString.sub(9); is not safe, as you're storing the address of a temporary. It is also wrong as anotherString is a pointer to a string object. To call the sub member function, you need to write anotherString->sub(9). And again, member function sub does not exist.
The first one of the second question is more correct than the second one; all you need to do is replace "\"" with '\"'.
The second one of the second question is wrong, as:
doubleQuote does not refer to the 10th character, but the string from the 10th character onwards
doubleQuote == "\"" may be type-wise correct, but it doesn't compare equality of the two strings; it checks if they are pointing to the same thing. If you want to check the equality of the two strings, use strcmp.
In C++, you can (and should) always use std::string (while remembering that string literals actually are zero-terminated character arrays). Use char* only when you need to interface with C code.
C-style strings need error-prone manual memory management, need to explicitly copy strings (copying pointers doesn't copy the string), and you need to pay attention to details like allocating enough memory to have the terminating '\0' fit in, while std::string takes care of all this automagically.
For the first question, the first sample, assuming sub will return a substring of the provided string.
For the second, none:
char doubleQuote = aString[9];
if( doubleQuote == '\"') { ... }
Erm, are you using string from STL?
(i.e. you have something like
#include <string>
#using namespace std;
in the beginning of your source file ;) )
then it would be like
string mystring("whatever:\"\""");
char anElem = mystring[9];
if (anElem=="\"") { do_something();}
or you can write
mystring.at(9)
instead of square brackets.
May be these examples can help.