How can I compare C-style strings? [duplicate] - c++

This question already has answers here:
Compare equality of char[] in C
(5 answers)
Closed 6 years ago.
The for loop reverses original string 's' and stores it in 'temp.'Temp is printed correctly. After which, s and temp are compared, but the result always shows NO. :(
#include<cstring>
#include <iostream>
using namespace std;
int main()
{
char s[100], temp[100];
cin >> s;
cout << strlen(s);
for(int i=0;i<strlen(s);i++)
{
temp[i]=s[strlen(s)-i];
}
cout << "temp is" << temp;
if(temp==s)
{
cout << "YES";
}
else
{
cout << "NO";
}
return 0;
}

You should use strcmp instead of == because the latter is merely a pointer comparison. Also, '\0' has to be used to end your string. And your current code would actually create an empty string because your string at position strlen(s) contains '\0'.
Then again, you should not work with char arrays in C++ on your own, rather use std::string as already pointed out in comments.

Related

The code below outputs 1 and 0 how ever i do not know why [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 2 years ago.
I understand that the code below is outputing the result of a boolean question but i do not understand why it outputs 1 and 0 instead of 1 and 1.
#include <iostream>
using namespace std;
int main()
{
string d = "abc", e = "abc";
char a[] = "abc", b[] = "abc";
cout << (d == e);
cout << (a == b);
return 0;
}
//outputs 10
i also tried outputing the value stored in variables a and b and got the same value for both
#include <iostream>
using namespace std;
int main()
{
string d = "abc", e = "abc";
char a[] = "abc", b[] = "abc";
cout << (d == e);
cout << (a == b);
cout << "\n" << a << "\n";
cout << b;
return 0;
}
// outputs 10
//abc
//abc
In C, std::string has a special operator== that actually compares the strings. Contrary to what you might read, std::strings are not equivalent to char arrays. Char arrays are essentially treated as pointers, so == compares the memory addresses, which are different, so the program will output 0.
For comparing 2 arrays of char you should use strcmp, the == operators compares the pointer addresses instead of the value itself. You can also iterate the arrays and compare element by element.

Issue regarding strrev() function in C++ language

I wrote a code to check if a string is a Palindrome or not. I assume logically my code is correct but the usage of strrev() function is incorrect. Please can anyone view it once? Thanks in advance
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char name[100];
int result;
cout<<name<<endl;
result=strcmp(name,strrev(name));
if(result==0){
cout<<"YES";
}
else{
cout<<"NO";
}
return 0;
}
strrev is not a standard C function, so it is anyone's guess as to what it actually does. In case if it operates on the passed string in-place then the construction strcmp(name,strrev(name)) is wrong as it will always return 0 (the strings are equal). And, of course, the fact that you don't initialize name is also an error.
First off, name is not even initialized. It does not hold any string whatsoever, it holds garbage value. So you should first either take user input using cin >> name; or just explicitly initialize it at point of declaration using char name[100] = "yourString"
Secondly, strrev will reverse the given string before returning it. So when you do strcmp(name, strrev(name)). strrev(name) already reverses the actual name string before strcmp can execute. So you're always comparing the same strings. You should compare a copy of name instead.
Like so-
char name[100], temp[100];
std::cin >> name;
strcpy(temp, name);
Now you should be able to print the result like before-
if (result == 0)
{
std::cout << "YES\n";
}
else
{
std::cout << "NO\n";
}
Also, off topic but you don't have to explicitly store the result, you can directly compare the strcmp result like so -
if (!strcmp(name, _strrev(temp)))
{
std::cout << "YES\n";
}
else
{
std::cout << "NO\n";
}
Or you could use ternary operator -
std::cout << strcmp(name, _strrev(temp)) ? "NO\n" : "YES\n";
Here's the full program-
#include<iostream>
#include<string>
int main()
{
int result;
char name[100], temp[100];
std::cin >> name;
strcpy(temp, name);
std::cout << strcmp(name, _strrev(temp)) ? "NO\n" : "YES\n";
return 0;
}
Last but not the least, please consider not using strrev, it is a very old C standard function. You should use std::reverse instead and operate using std::string instead of C-Style strings. If you still want to keep using C style strings, use _strrev if that is available to you.
More info on C and C++ style strings

Using pointers to find positions of characters between unbalances parentheses

I am given a C++ programming problem: In a string I need to find wether or not there are balanced parentheses. If not, using pointers I should find position of the characters between unclosed parentheses (between second opening and nearest closing).
The problem statement is a bit confusing, I know. I think it should work somehow like that:
Input #1:
((aba)aaab)
Output:
OK.
Input #2:
(aa(a)ab
Output:
Parentheses not balanced: between characters 1 and 6.
Code below solves part of problem with the closed parentheses check and also there is a structure to keep the address of the opening parenteses. I am not sure how exactly to use pointers for that purposes, some attempts did not give any result, so I need some help here.
#include<iostream>
#include<string>
#include<stack>
using namespace std;
struct br_data{
char br_t;
char *cptr; //store the address of the opening parenthesis
};
int main (){
string input;
int addr;
br_data br;
getline(cin, input);
stack<br_data> braces;
char *a = input[0];
auto init_char = static_cast<void*>(&a); //store the address of the first character in the input string
cout << static_cast<void*>(&a) << endl; //gives the address in memory
for(auto c: input) {
if (c == '(') {
br.br_t = c;
br.cptr = &c; //storing the address of the first parenhesis
braces.push(br);
} else if (c == ')' ) {
if (braces.empty())
cout << "This line does not contain unclosed parentheses\n";
if (!braces.empty())
braces.pop();
}
}
if (!braces.empty()){
//int addr = br.cptr;
cout << "This line does not contain unclosed parentheses\n";
//int pos = (&br.cptr) - (&a); //how to calculate the position??
cout << "Position of the second opening parenthis is " << () << endl;
//cout << "Position of the nearest closing parenthis is " << -how?? (static_cast<void*>(&br.cptr)) << endl;
}
if (braces.empty()){
cout << "Parentheses are balanced in this line\n";
}
return 0;
}
When you write
br.cptr = &c; //storing the address of the first parenhesis
you're actually storing the address of a local object of char type declared earlier:
auto c: input
By the moment you exit the loop it is officially dangling.
One simplest solution would be to actually consider string's characters, not their local copies:
for(auto &c: input) {
(and, even better, change auto into char for better clarity keeping source length the same). Then you can go on and see how your solution needs to be fixed further.
(A few extra free advice: input[0] is a rvalue reference of type char so it makes no sense to assign it to a variable of type char *, and what you try to do in that line is actually written as char *a = input.c_str(); or input.data() or even &input[0], pick the best option; and br.cptr is of type pointer-to-char already, so the character's position in a string would be calculated as br.cptr - a, you need to subtract the pointers themselves, not their addresses.)
#include <iostream>
using namespace std;
int main(){
char str[]="Hello Programming";
char *ptr;
char ch;
char s;
s='n';
ptr=str;
cout<<"To be found Character"<<endl;
cin>>ch;
while(*ptr++ != '\0')
if(*ptr==ch)
s='y';
if (s=='y')
cout<<"FOUND";
else
cout<<"not found";``
return 0;
}

C++ How to pass 2 arrays (of strings) to a function, and compare to a string [duplicate]

This question already has answers here:
Size of array object passed to function
(4 answers)
Closed 7 years ago.
I'm a C++ beginner, so talk to me like I'm 5.
Here's what I'm trying to do:
Take user's input into a string userInput
Pass userInput, along with 2 arrays (answers and outcomes), into a function answerCheck
Compare userInput with answers array
If there's a match, output string from outcomes
If no match, loop, ask for userInput
I output the size of answers with answersSize. It outputs 1 instead of the expected 2.
I can't figure out how to pass the information in the arrays to the answerCheck function.
Any suggestions?
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int question1();
bool answerCheck(string[], string[], string);
int main() {
question1();
system("pause");
return 0;
}
int question1() {
cout << "Do you want to go LEFT or RIGHT?" << endl;
string answers[2] = { "left", "right" };
string outcomes[2] = { "you went left", "you went right" };
string userInput = "";
getline(cin, userInput);
// outputs correct size of answers array for testing ======
int answersSize = sizeof(answers) / sizeof(string);
cout << "Correct size of answers: "<< answersSize << endl;
// ========================================================
answerCheck(answers, outcomes, userInput);
return 0;
}
bool answerCheck(string answers[], string outcomes[], string userInput){
int answersSize = sizeof(answers) / sizeof(string);
cout << "Size of answers: "<< answersSize << endl;
for(int i=0; i < answersSize; i++){
if(userInput.find(answers[i]) != string::npos){
cout <<"\n" << outcomes[i] <<"\n" << endl;
return true;
}
}
cout << "Try putting in something else." << endl;
return false;
}
The problem is here:
int answersSize = sizeof(answers) / sizeof(string);
If you print it out, you will find that sizeof(answers) is the size of a pointer (4 or 8 bytes), not the size of the entire array. You need to pass the array size in as a function argument, or else use a class type like std::vector which encapsulates this in a more C++ way.
A general advice for beginners would be to use the C++ such as classes std::vector instead of plain C arrays. So in your example, instead of
string answers[2] = { "left", "right" };
use
std::vector<std::string> answers{ "left", "right" };
and declare your function
bool answerCheck(std::vector<string> const& answers,
std::vector<string> const&outcomes,
string const& userInput)
If you are reading a introductory book and it starts by introducing C-style code first, I would throw it away. A good introduction to C++ is e.g. https://isocpp.org/tour.

Capitalizing first letter in each word [duplicate]

This question already has answers here:
toupper returns integer rather than char
(4 answers)
Closed 7 years ago.
Output is same as the input where am i making the mistake?
Pls check the test version, it prints the ASCII code of 'A' but not A why is it so?
The 1st if condition in the loop is to make sure that the string starts with a valid character only and not space.
void caps(char* p)
{
char* begin=NULL;
char* temp=p;
while(*temp)
{
if((begin == NULL) && (*temp!= ' '))
begin=temp;
if(begin && ((*(temp+1) == ' ' ) || (*(temp+1)=='\0')))
{
toupper(*temp);
begin=NULL;
}
temp++;
}
cout<<p;
}
int main()
{
char str[]={"i like programming"};
cout<< str <<endl;
caps(str);
return 0;
}
Test
If I use printf("%c",toupper(a)) it prints 'A' correctly.
#include <iostream>
#include <ctype.h>
using namespace std;
int main()
{
char a= 'a';
cout<<toupper(a); //prints ASCII code of A(65) but why not 'A' ?
return 0;
}
Well, in the first code cout << str << endl; str is a pointer(it's type is char*). To output the first character of str, use cout << str[0]; or cout << *str;. And toupper() returns int, not char, so you need to cast the result:
cout << (char)toupper(a);