What's the difference between these two given examples - c++

I'm a beginner in C++ and programming itself actually. I just want to ask, What's the difference between these 2 examples. What is the difference between "len = strlen(str1)-1" and "i = strlen(str1)-1"
Top part of the code will be like this:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char str1[20],str2[20];
int c, i ,j, len;
cout<<"Enter a word: ";
cin.getline(str1, 20);
Example 1:
//reverse
for (i = strlen(str1)-1, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does not work because the value of 'c' will be -1 if the input
is "lol" which is palindrome*/
and Example 2:
//reverse
len = strlen(str1)-1;
for (i = len, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does work in other hand, because of the variable "len"*/
the rest of the code will be like this
if(c == 0){
cout<<"It is a Palindrome";
}
//if the value of C is !=0
else{
cout<<"It is not a Palindrome";
}
}
Why is that? Thanks in advance for those who will answer. :)

Both examples are same except first uses an extra variable len.
This code is actually reversing the string. If str1 contains "123" then str2 will contain "321".
Function strlen(str1) returns the length of str1 but in C++ index of Arrays start from 0 that is why the last element index will be one less than length, hence strlen(str1) - 1.
UPDATE
Even with updated information the answer to first question remains same that both examples are same in nature. Difference in results is a mare co-incident due to a reason explained below.
char str1[20],str2[20];
This code creates two array of 20 char but not initialized. This means the initial values can be random.
Now when you call cin.getline(str1, 20); it not only writes the string you entered but adds a terminating '\0' character at the end of it. Our reversing logic only reverse the string but does not insert terminating '\0' at the end of str2 which means str2 is much longer (until it finds a '\0') than str1. Due to this they never compare correctly.
A simple solution to this issue can be zero-filling the arrays before using them and in C++ there is a simple way to do that:
char str1[20] = { 0 }, str2[20] = { 0 };
It is always a good practice to zero-fill your arrays if you are going to use then as strings.

Related

How do you break a long string into words and iterate through each character of word and if they match increment a char count using stringstream

int MatchString::comparsion(string newq, string oldq){
//breaks down the string into the smaller strings
stringstream s1(newq);
stringstream s2(oldq);
string new_words;
string old_words;
int word_count = 0;
while(s1>>new_words&&s2>>old_words){
for(int i = 0; i<new_words.length();i++){
for(int j = 0; j<old_words.length();j++){
char a = new_words[i];
char b = old_words[j];
if(a == b){
char_count++;
}
else{
j++;
}
}//end of 2nd for
}//end of for
}
return char_count;
}
I'm currently trying to make a function that takes in two strings and breaks them down into words then into chars. Afterward, I try to compare the value of each char and see if they equal each other. And if they do I increment a char_count by 1. Else I increment j so I compare next char in string 2 with string 1. I need to use this char_count value later to develop another algorithm because I need it to calculate a percentage difference between the two strings which is why I return it at the end because including that calculation with this method would be a bit messy. However when cout the return value I get something completely wrong. I don't know what I'm doing wrong can you please help.
Your j++ under else in the for-loop is redundant, if I'm correct. Allow your for-loop to naturally advance its iterator, don't force it within else{}.

Beginner - What's wrong with my "produce word backwards" program?

#include <iostream>
#include <string>
using namespace std;
int main()
{
string word, wordbackw;
getline(cin, word);
int size = word.size();
for (int i = 0; i < size ; i++)
word[size-1-i] = wordbackw[i];
cout << wordbackw << endl;
return 0;
}
The only thing that appears in the cmd is my input.
Thanks for any help.
EDIT: Sorry, forgot to add cout to the code.
You must first resize wordbackw to the same size as word:
You could either initialize wordbackw = word; before the loop and print out the result in word.
Or you could resize wordbackw before the loop and copy word letters to wordbackw letters (you do the oposite for now), and display the result in wordbackw
Two issues:
You are overriding the input that you read with non-existent characters when you do word[size-1-i] = wordbackw[i]; try doing wordbackw.push_back(word[size-1-i]);
You are not printing anything to the standard output after reading. Do this
cout << wordbackw << endl;
You're missing any kind of code to display the reversed string. You only reversed it in memory.
Try adding something to display the text after you reverse it, such as
cout << wordbackw;
Oh, well and also your word swapping code looks backwards in a couple of ways. You load it into word but then try to set word to the reverse of wordbackw, which is empty. Also the indexing looks off - you're assigning locations in an empty string, and you're indexing forwards through the source string rather than backwards. So you'd want to do something more like:
for (int i = size - 1; i >= 0 ; i--)
wordbackw += word[i];
The object wordbackw is empty. So you may not apply the subscript operator for the object. Also you should at least exchange the operands in this statement
word[size-1-i] = wordbackw[i];
provided that the operands will be written correctly.
You could write instead of this code snippet
int size = word.size();
for (int i = 0; i < size ; i++)
word[size-1-i] = wordbackw[i];
the following
wordbackw.reserve( word.size() );
for ( auto i = word.size(); i != 0 ; i-- )
wordbackw.push_back( word[i - 1] );
Or
wordbackw.reserve( word.size() );
for ( auto i = word.size(); i != 0 ; i-- )
wordbackw += word[i - 1];
Or you could do the same without using the loop. For example
wordbackw.assign( word.rbegin(), word.rend() );

C++: first index of an empty array won't populate its given character with .resize(), but every other character following does

I'm new to C++ so please forgive me if this is basic.
I have a basic encrypting algorithm below. Everything generally works as it should, except that the encrypted output of the first index of the string 'text' is not appended to the string 'cipher'. Every index following the first is appended as it should.
Any ideas with this one?
Code:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string text = "Do not worry about your difficulties in Mathematics. I can assure you mine are still greater.";
string cipher;
int tSize = text.size();
int cSize = cipher.size();
for (int i = 0; i < tSize; i++)
{
if (isalpha(text[i]))
if (isupper(text[i]))
{
if (text[i] < 'V') cipher.resize(cSize++, text[i] + 4);
else cipher.resize(cSize++, text[i] - 22);
}
else
{
if (text[i] < 'v') cipher.resize(cSize++, text[i] + 4);
else cipher.resize(cSize++, text[i] - 22);
}
else cipher.resize(cSize++, text[i]);
}
cout << cipher << endl;
}
Output
s rsx asvvc efsyx csyv hmjjmgypxmiw mr Qexliqexmgw. M ger ewwyvi csy qmri evi wxmpp kviexiv.
Thanks in advance!
The problem is that the variable cSize is initially zero, and you use post increment when resizing cipher.
Remember that post-increment returns the old value, the value before the increment. That means the very first call to resize will resize the string with the size zero.
The simple solution is to use pre increment, as in ++cSize, instead. Or initialize cSize to 1.

Logical error from std string find method and count algorithm

When I was about to solve a project euler problem in C++, this was some of the experimentation code I made. It produced a quite unexpected result, so I solved it in an other programming language. But I really want to understand why this error occured. The part one of the code executes as expected, it does not print AAAA. But in part two, the logically equivalent code (the if statement) executes when the variable s is AAAA. And I have no idea why. I hope I made my problem clear, every answer given is highly appreciated! Thanks :)
Note: i'm using count from <algorithm>
#include <iostream>
#include <algorithm>
using namespace std;
int main (int argc, char** argv) {
string alt = "LOA";
// CODE PART 1
string stringToFind = "AAA";
string df = "AAAA";
if (df.find(stringToFind) == string::npos && count(df.begin(), df.end(), 'L') <= 1) {
cout << df; // this does not print AAAA
}
/* CODE PART 2:
this was an attempt to print out every four length string combination
of the characters L, O, A where strings with three A's in a row and
more than one L were excluded.
*/
for (size_t i = 0; i < 3; i++) {
char c1 = alt[i];
for (size_t iT = 0; iT < 3; iT++) {
char c2 = alt[iT];
for (size_t itr = 0; itr < 3; itr++) {
char c3 = alt[itr];
for (size_t itrI = 0; itrI < 3; itrI++) {
char c4 = alt[itrI];
string s = string(&c1)+string(&c2)+string(&c3)+string(&c4);
if (s.find(stringToFind) == string::npos && count(s.begin(), s.end(), 'L') <= 1) {
cout << s << endl; // this however, does print out AAAA
}
}
}
}
}
return 0;
}
You have written
string s = string(&c1)+string(&c2)+string(&c3)+string(&c4);
You meant:
string s = string(1,c1)+string(1,c2)+string(1,c3)+string(1,c4);
or
string s = string(&c1,1)+string(&c2,1)+string(&c3,1)+string(&c4,1);
In your code, you have invoked the string constructor which takes a pointer to a nul-terminated array of char, but you given it a pointer to a single char. That's going to invoke all sorts of undefined behaviour.
Either invoke the constructor that takes a a counter + a single char or, the one which takes a pointer and a count, and you can tell it there is exactly one character at that address.
Edit There is no constructor which takes a single char. You have to give it a count + char. Which means it's not so pretty.

count empty char cells c++

For goodness' sake, it's seems such a simple piece of code and I just can't figure out where I went wrong.
int count = 0;
for (int i = 0; i<10;i++){
if (chararray[i]=='\0' && i == 0){
cout << "Empty \n";
break;
}
if (chararray[i]!='\0') {
count = count ++;
}
}
cout << "Deleted " << count << "elements \n";
So the basic idea is that it goes through the array and if it's empty, then returns "Empty" and if not then it counts all the non empty cells and returns how many of them there were. If it makes any difference, I'm putting this under deconstructor method.
Generally it works fine, it just won't COUNT right. It either counts all or none.
UPDATE!
Thank you all! I removed the count = count++ line with ++count and it displayed more correct results than before, but not for all test values (and I promise not to make this same mistake again). As it is, I took the advice to use strlen function as there isn't a specific need for a 0 in place of, well, nothing. Also it made the code much, much shorter. Thank you!
You titled your question as
count empty char cells c++
however as it is seen in the code snippet the count is increased when an element of the array is not equal to '\0'
if (chararray[i]!='\0') {
count = count ++;
}
So what is the empty char cell that you are going to count?
Take into acccount that this statement
count = count ++;
has undefined behaviour because applying the side effect of operaator ++ is not sequenced relative to the left operand assignment.
If the array contains a string and you want to know whether it is empty and how many characters in the string then you should use standard C function strlen
If the array does not contain a string and elements with value '\0' can be in any place of the array then that tp count non-zero elements you should use standard algorithm std::count_if
For example
#include <algorithm>
#include <functional>
//..
int n = std::count_if( chararray, chararray + 10,
std::bind2nd( std::not_equal_to<char>(), '\0' ) );
if (chararray[i]=='\0' && i == 0){
This line looks for a null value and then checks if it is at index 0
Try this:
if(chararray[i]==`\0`){
to break on the first null value and stop counting.
Also:
Please please please change this:
if (chararray[i]!='\0') {
count = count ++;
It is Undefined Behaviour (UB) and will very likely not be working as intended or break at some later point.
It should be:
if (chararray[i]!='\0') {
count ++;
Assuming chararray has type char [] you can simply use std::count
auto num_items = std::count( std::begin( chararray ),
std::end( chararray ),
'\0'
); // returns 0 or number of occurrence
One problem:
count = count ++;
is undefined behavior: it could result in something like...
tmp = count; // count == 0
count++;
count = tmp; // count == 0
or...
tmp = count; // count == 0
count = tmp;
count++; // count == 1
Try ++count; instead.