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

#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() );

Related

2d array comparing with char

I have an array that reads data from a file, the data is binary digits such as 010011001001 and many others so the data are strings which I read in to my 2d array but I am stuck on comparing each value of the array to 0. Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000][12];
int i = 0, zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while(!inFile.eof())
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 12; j++)
{
inFile >> myArr[i][j];
j++;
}
i++;
}
}
for(int j = 0; j < 12; j++)
{
for(int i = 0; i < 5000; i++)
{
if(myArr[i][j].compare("0") == 0)
{
zeroCount++;
}
else
{
oneCount++;
}
i++;
}
if(zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
j++;
}
}
some input from the text file:
010110011101
101100111000
100100000011
111000010001
001100010011
010000111100
Thank you for editing you question and providing more information. Now, we can help you. You have 2 major misunderstandings.
How does a for loop work?
What is a std::string in C++
Let us start with the for loop. You find an explanation in the CPP reference here. Or, you could look also at the tutorial shown here.
The for loop has basically 3 parts: for (part1; part2; part3). All are optional, you can use them, but no need to use them.
part1 is the init-statement. Here you can declare/define/initialize a variable. In your case it is int i = 0. You define a variable of data type int and initialize it with a value of 0
part2 is the condition. The loop will run, until the condition becomes false. The condition will be check at the beginning of the loop.
part3 is the so called iteration-expression. The term is a little bit misguiding. It is basically a statement that is executed at the end of the loop, before the next loop run will be executed and before the condition is checked again.
In Pseudo code it is something like this:
{
init-statement
while ( condition ) {
statement
iteration-expression ;
}
}
which means for the part of your code for(int j = 0; j < 12; j++)
{
int j = 0; // init-statement
while ( j < 12 ) { // while ( condition ) {
inFile >> myArr[i][j]; // Your loop statements
j++; // Your loop statements PROBLEM
j++; // iteration-expression from the for loop
}
}
And now you see the problem. You unfortunately increment 'j' twice. You do not need to do that. The last part3 of the for loop does this for you already.
So please delete the duplicated increment statements.
Next, the std::string
A string is, as its names says, a string of characters, or in the context of programming languages, an array of characters.
In C we used to write actually char[42] = "abc";. So using really a array of characters. The problem was always the fixed length of such a string. Here for example 42. In such an array you could store only 41 characters. If the string would be longer, then it could not work.
The inventors of C++ solved this problem. They created a dynamic character array, an array that can grow, if needed. They called this thing std::string. It does not have a predefined length. It will grow as needed.
Therefore, writing string myArr[5000][12]; shows that you did not fully understand this concept. You do not need [12], becuase the string can hold the 12 characters already. So, you can delete it. They characters will implicitely be there. And if you write inFile >> myString then the extractor operator >> will read characters from the stream until the next space and then store it in your myString variable, regardless how long the string is.
Please read this tutorial about strings.
That is a big advantage over the C-Style strings.
Then your code could look like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000];
int zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while (!inFile.eof())
{
for (int i = 0; i < 5000; i++)
{
inFile >> myArr[i];
}
}
for (int i = 0; i < 5000; i++)
{
zeroCount = 0; oneCount = 0;
for (int j = 0; j < 12; j++)
{
if (myArr[i][j]== '0')
{
zeroCount++;
}
else
{
oneCount++;
}
}
if (zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
}
}
But there is more. You use the magic number 5000 for your array of strings. This you do, because you think that 5000 is always big enough to hold all strings. But what, if not? If you have more than 5000 strings in your source file, then your code will crash.
Similar to the string problem for character arrays, we have also a array for any kind of data in C++, that can dynamically grow as needed. It is called std::vector and you can read about it here. A tutorial can be found here.
With that you can get rid of any C-Style array at all. But please continue to study the language C++ further and you will understand more and more.
Ther are more subtle problems in your code like while(!inFile.eof()), but this should be solved later.
I hope I could help

What's the difference between these two given examples

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.

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.

Last word in a sentence is not printing after the sentence is reversed

When I am reversing a sentence, below code is unable to print the last word in the sentence after it is reversed.
#include "stdafx.h"
#include "conio.h"
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
char sentence[80]={0};
cout<<"Input the string: ";
cin.getline(sentence,80,'\n');
int length=strlen(sentence);
int check=0;
for(int i=length; i>0; i--)
{
if(sentence[i]!=' ')
{
check++;
}
else
{
for(int j=i; j<(check+i); j++)
cout<<sentence[j+1];
cout<<" ";
check=0;
}
}
return 0;
}
If we enter the Sentence as "My Name is Rakesh" the output it is displaying as "Rakesh is Name". It is not displaying "My".
I have found two mistakes in your code.
Mistake # 01:
You are not iterating over the whole input. You are skipping the first index of the array because of the statement i>0.
Possible Solution:
You should change the condition of loop from i>0 to i>=0 in order to iterate the whole input.
Mistake # 02:
You are not checking the case of first word of the input, which is My in your case. You are printing the word in case the condition of sentence[i]!=' ' gets false so what if sentence[0] is not a space character then the statement check++ will be executed and then the loop will be terminated so the first word of input will not be printed.
Possible Solution:
You should handle this case either by printing the word outside the loop or by adding an if condition in the loop to print the word in case if i == 0 && sentence[i] != ' '. I have updated the code according to the first method and now it works fine.
Updated Code:
int i = 0;
for (i = length; i>=0; i--)
{
if (sentence[i] != ' ')
{
check++;
}
else
{
for (int j = i; j<(check + i); j++)
cout << sentence[j + 1];
cout << " ";
check = 0;
}
}
//Printing the missing word outside the loop
for (int j = i; j<(check + i); j++)
cout << sentence[j + 1];
Hope this helps.
Well,
for(int i=length; i>0; i--)
ends when i=1, and array index starts from 0, so that's ONE of problems here.
Change i>0 to i>=0.
If you begin and end your sentence with a space character it will work. You need to treat the space character and your end of string (null terminator) and your start of string as the same delimiter in this case, so you detect the start of the string, end of the string as well as the spaces in between
Try entering: " My Name is Rakesh " (with a space at the start and end)
to see the scope of your problem...Use a debugger to step through
(You indirectly manage the null termintor - by using strlen; and you capture all the space characters, but what do you do with the string remaining, that is the word delimited by being at the beginning of the String - at index 0)

C++: using a substring to create a new string

I have a string..."APPLES" and i'm having difficulty using substring to effectively manipulate the string. My goal is to add a '-' every 3 characters. My problem is that when "APPLES" goes through, it returns "APP-ES-" which is incorrect, I'm trying to make it return "APP-LES-" any suggestions? Here is my code thus far...
for(int j = 0; j <= str.length(); j++){
str_substr += str.substr(j,j+3);
str_substr = str_substr + '-';
j = j+3;
cout << str_substr;
}
Just build a separate string by copying the relevant parts.
std::string s;
for(size_t i = 0; i < str.length(); i += 3) {
s += str.substr(i, 3) + "-";
}
(Just so you note it for sure: str.substr(j,j+3); is incorrect, it won't copy 3 characters, it will copy j + 3 characters. Read the documentation more carefully.)
You're incrementing j twice:
for(int j = 0; j <= str.length(); j++){
^-- once here
...
j = j+3;
^-- and again here
Also, it looks like you might get two -s at the end of a string with a length that's a multiple of three, since you're checking for j <= str.length() instead of j < str.length() Try:
for(size_t j = 0; j < str.length(); j+=3){
str_substr += str.substr(j,3) + '-';
}
cout << str_substr;
Since you're apparently just copying the result to cout, anyway, perhaps it's easiest to skip the intermediate string, and just copy 3 characters to cout, then write a -, three more characters, etc.
#include <string>
#include <iterator>
#include <iostream>
int main(){
std::string input("APPLES");
size_t len = 3;
for (size_t pos = 0; pos < input.length(); pos += len)
std::cout << input.substr(pos, len) << "-";
}
If you need to modify the existing string, you probably want to start by computing the number of dashes you're going to insert, then work from the end of the string back to the beginning, moving each character directly to its destination. If you start at the front and insert dashes where needed, it ends up as an O(N2) algorithm. Working from end to beginning and moving each character directly to its destination is O(N) instead.