Warnings and Errors with declaration of multi-character character - c++

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).

Related

scanf function for strings

The problem is simple, the code below does not work. it says Process finished with exit code -1073740940 (0xC0000374). Removing ampersand does not change anything.
int main(){
string x;
scanf("%s",&x);
cout << x;
}
scanf() with the %s format specifier reads bytes into a preallocated character array (char[]), to which you pass a pointer.
Your s is not a character array. It is a std::string, a complex object.
A std::string* is not in any way the same as a char*. Your code overwrites the memory of parts of a complex object in unpredictable ways, so you end up with a crash.
Your compiler should have warned about this, since it knows that a char* is not a std::string*, and because compilers are clever and can detect mistakes like this despite the type-unsafe nature of C library functions.
Even if this were valid via some magic compatibility layer, the string is empty.
Use I/O streams instead.
You cannot pass complex objects through the ... operator of printf/scanf. Many compilers print a warning for that.
scanf requires a pointer of type char* pointing to sufficient storage for an argument of %s. std::string is something completely different.
In C++ the iostream operators are intended for text input and output.
cin >> x;
will do the job.
You should not use scanf in C++. There are many pitfalls, you found one of them.
Another pitfall: %s at scanf is almost always undefined behavior unless you you really ensure that the source stream can only contain strings of limited size. In this case a buffer of char buffer[size]; is the right target.
In any other case you should at least restrict the size of the string to scan. E.g. use %20s and of course a matching char buffer, char buffer[21];in this case. Note the size +1.
You should use cin. But if you want to use scanf() for whatever reason and still manipulate your strings with std::string, then you can read the C-string and use it to initialize your C++ string.
#include <iostream>
#include <cstdio>
#include <string>
using std::cout;
using std::string;
int main()
{
char c_str[80];
scanf("%s", c_str);
string str(c_str);
cout << str << "\n";
}
If you want to use strings, use cin (or getline).
string s;
cin>>s; //s is now read
If you want to use scanf, you want to have a char array (and don't use &):
char text[30];
scanf("%s", text); //text is now read
You can use char[] instead of string
include <iostream>
using namespace std;
int main()
{
char tmp[101];
scanf("%100s", tmp);
cout << tmp;
}

Comparing two strings in c++ issue.

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 .

Comparison with string literal C++

I'm writing a function for a program that allows a student to copy a template text file. This function checks the user's input to see if his desired template is allowed for his class.
I'm getting the error "Comparison with string literal results in unspecified behavior" on lines 21 and 25. I have done "cout << name" to verify that variable is storing correctly, which it is, so I know that's not the problem.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
//TEMPLATE CHECK
//First you check to see if the student is allowed to use the template
int templateCheck()
{
//Declare file name variable
char name[256];
//Prompt for user input
cout << "Enter file name: ";
//Cin user input
cin >> name;
//Begin check
//CS221 is the first template you can't use
if(name == "/home/cs221Temp.txt")
cout << "You are not allowed to use CS221 templates./n";
//CS 321 is the other template you can't use
else if (name == "/home/cs321Temp.txt")
cout << "You are not allowed to use CS321 templates./n";
//Any others are okay (I commented these out since I'm just working on this function by itself)
//else
//copyTemplate();
return 0;
}
This statement
if(name == "/home/cs221Temp.txt")
compares for pointers being equal (which is unlikely), not their contents.
What you actually want is
if(strncmp(name,"/home/cs221Temp.txt",256) == 0)
or
std::string name;
in your function.
You can't compare two C-style strings by ==ing them. (C-style string literals just give you a pointer to the first character in a sequence of characters in RAM, ended by a 0 valued character, so you'd be comparing addresses instead of strings).
What you want to use would be the strcmp function from stdlib.
However, you're writing C++, not C.
So, I recommend using the string class, which has an overloaded == operator, so you can do
if (string1 == string2)
In C/C++ (unlike in "similar" languages like JavaScript) when you use == on "strings" you are comparing pointers.
If you want to compare the strings' content, then you must use functions that are designed for that purpose. Like strcmp() from the standard C library

C++ comparing a char to a string literal [duplicate]

This question already has answers here:
c++ compile error: ISO C++ forbids comparison between pointer and integer
(5 answers)
Closed 5 years ago.
Beginning programmer here...
I'm writing a very simply program for my computer science class and I ran into an issue that I'd like to know more about. Here is my code:
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
char courseLevel;
cout << "Will you be taking graduate or undergraduate level courses (enter 'U'"
" for undergraduate,'G' for graduate.";
cin >> courseLevel;
if (courseLevel == "U")
{
cout << "You selected undergraduate level courses.";
}
return 0;
}
I'm getting two error messages for my if statement:
1) Result of comparison against a string literal is unspecified (use strncmp instead).
2) Comparison between pointer and integer ('int' and 'const char*').
I seem to have resolved the issue by enclosing my U in single quotes, or the program at least works anyway. But, as I stated, I'd simply like to understand why I was getting the error so I can get a better understanding of what I'm doing.
You need to use single quotes instead.
In C, (and many other languages) a character constant is a single character1 contained in single quotes:
'U'
While a string literal is any number of characters contained in double quotes:
"U"
You declared courseLevel as a single character: char courseLevel; So you can only compare that to another single char.
When you do if (courseLevel == "U"), the left side is a char, while the right side is a const char* -- a pointer to the first char in that string literal. Your compiler is telling you this:
Comparison between pointer and integer ('int' and 'const char*')
So your options are:
if (courseLevel == 'U') // compare char to char
Or, for sake of example:
if (courseLevel == "U"[0]) // compare char to first char in string
Note for completeness: You can have mulit-character constants:
int a = 'abcd'; // 0x61626364 in GCC
But this is certainly not what you're looking for.
Rapptz is right, but I think some more elaboration should help...
courseLevel == "U"
In C and C++, double-quotes create string literals - which are arrays of characters finishing with a numerical-0 ASCII-NUL terminating sentinel character so programs can work out where the text ends. So, you basically are asking if a character is equal to an array of characters... they just can't be compared. Similar questions that are valid are:
does this character variable hold a specific character value: courseLevel == 'U'
does this character variable appear in a specific array: strchr(courseLevel, "U")
does this character variable match the first element in a specific array: courseLevel == "U"[0]
Of course, the first one of these is the one that makes intuitive sense in your program.
The reason why you get an error is because string literals in C and C++ end with a null terminated character \0 while single characters don't. So when you compare to a char to a string literal you're comparing the character literal to a char array {'U','\0'}.

c++ creating ambigram from string

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.