Comparing two vectors might be giving me an error - c++

So the idea behind this is that a user inputs a message, and the message gets translated to Morse code. It is a homework assignment I've been working on for over 8 hours today. It's also my first time seriously working with classes.
When run, I get only one error on line 64. The error I got makes no sense (and it's huuuuge so I don't want to include it unless asked). I suspect the issue is that the originalMessage vector and alphaCode vector are different vector types (string & char respectively).
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Code
{
private:
vector<char> alphaCode;
vector<string> morseCode;
vector<string> originalMessage;
vector<string> finalMessage;
public:
Code();
void encoder(vector<string> input);
void display();
};
Code::Code():alphaCode(), morseCode(28)
{
//Building alphaCode
for (char c='A'; c<='Z'; c++) alphaCode.push_back(c);
alphaCode.push_back(' ');
alphaCode.push_back('.');
//Building morseCode
morseCode[0] =".-";
morseCode[1] ="-...";
morseCode[2] ="-.-.";
morseCode[3] ="-..";
morseCode[4] =".";
morseCode[5] ="..-.";
morseCode[6] ="--.";
morseCode[7] ="....";
morseCode[8] ="..";
morseCode[9] =".---";
morseCode[10] ="-.-";
morseCode[11] =".-..";
morseCode[12] ="--";
morseCode[13] ="-.";
morseCode[14] ="---";
morseCode[15] =".--.";
morseCode[16] ="--.--";
morseCode[17] =".-.";
morseCode[18] ="...";
morseCode[19] ="-";
morseCode[20] ="..-";
morseCode[21] ="...-";
morseCode[22] =".--";
morseCode[23] ="-..-";
morseCode[24] ="-.--";
morseCode[25] ="--..";
morseCode[26] =".......";
morseCode[27] ="x";
}
void Code::encoder(vector<string> input)
{
originalMessage = input;
for (int i = 0; i < originalMessage.size(); i++)
{
for (int j = 0; j < alphaCode.size(); j++)
{
if (originalMessage[i] == alphaCode[j])
{
finalMessage.push_back(morseCode[j]);
finalMessage.push_back(" ");
}
}
}
}
void Code::display()
{
for (int x; x < finalMessage.size(); x++) cout << finalMessage[x];
}
//------------------------------------------------------------------------------
int main()
{
vector<string> message;
string temp;
cout << "Input:" << endl;
cin >> temp;
message.push_back(temp);
Code c1;
c1.encoder(message);
c1.display();
}

You have a couple of problem in your source code.
The first problem is message variable:
vector<string> message;
Could be changed to:
string message;
And change other parts of your code, based on this change.
The second problem backs to
for (int x; x < finalMessage.size(); x++) cout << finalMessage[x];
variable x is not initited, initite it or write a better loop like this:
for (const auto& x : finalMessage) cout << x;

Please read the error message :
prog.cpp:64:36: error: no match for 'operator==' (operand types are 'std::basic_string' and 'char')
if (originalMessage[i] == alphaCode[j])
if (originalMessage[i] == alphaCode[j])
originalMessage is a vector<string> while alphaCode is vector<char>
There is no way you can compare char with a string
You may want to change your function this way:
void Code::encoder(vector<string> input)
{
originalMessage = input;
for (int i = 0; i < originalMessage.size(); i++)
{
string i_string = originalMessage[i]; // get the string here
for (int j = 0; j < alphaCode.size(); j++)
{
if (i_string.at(i) == alphaCode[j]) // get the char in string
{
finalMessage.push_back(morseCode[j]);
finalMessage.push_back(" ");
}
}
}
}
EDIT
Basically, we want to extract char information from the string
for (int i = 0; i < originalMessage.size(); i++) {
string i_string = originalMessage[i];
for (int j =0; i < i_string.size(); j++) {
char at_j = i_string.at(j);
// find this at_j in alphaCode
// enncode
}
}

Related

Character counter returning incorrect value for char[n] array

I am writing a C++ program for homework, and it needs to count the characters in a char arr[n] string. However, my counter keeps returning the wrong values. I have looked through other answers to similar questions, however, they are not specific to C++ and none of the answers explain the value I am getting.
#include<iostream>
using namespace std;
#include<string.h>
#include <stdlib.h>
class Counter
{
public:
char word[20];
int totChar{ 0 };
void setWord(char word)
{
this->word[20] = word;
}
void setCount(int totChar)
{
this->totChar = totChar;
}
int getLength()
{
return totChar;
}
void charCount()
{
int n = 0;
for (int i = 0; word[i] != '\0'; i++) {
if (word[i] != '\0')
{
n++;
}
}
setCount(n);
}
};
int main()
{
char text[20];
cout << "Enter the string:" << endl;
cin >> text;
Logic input;
input.setWord(text[20]);
input.charCount();
// input.resetWord();
cout << input.getLength();
}
So it seems you haven't figured out how arrays and C strings work in C++ yet.
void setWord(const char* word)
{
strcpy(this->word, word);
}
and
Logic input;
input.setWord(text);
Your code is a bit weird, I guess you are just experimenting, but I think those two changes should make it work.

Encrypting a String in C++

I am in desperate need of help with my C++ program that is supposed to encrypt a string that the user inputs (source) and saves the encrypted string to another string (destination).
Before the string is encrypted, it runs through the lowerCaseString() function where it converts source to all lowercase. This function works perfectly fine.
Can you help my make my program properly display the encrypted message? I am new to C++.
My error:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at: __n (which is 0) >= this->size() (which is 0)
#include <iostream>
#include <string>
#include <ostream>
#include <fstream>
#include <sstream>
#include <cctype>
#include <vector>
using namespace std;
string lowerCaseString(string &source);
bool substitution(string &source, string cipherKey, string &destination);
int main()
{
string source;
string cipherKey = "qwertyuiopasdfghjklzxcvbnm";
string destination;
ifstream inFile;
cout << "Please enter a string: " << endl;
cin >> source;
//eventually has to write to a file, but I want to get the cipher part working first
//cin >> cipherKey;
// inFile.open("C:/Users/ellio/OneDrive/Desktop/Freshman Semester 2/ECE 1080C/ECE Labs/otherlabfiles/small-file.txt"); /*make necessary change for
// file access path*/
// if (!inFile){
// cout << "Input file cannot be opened" << endl;
// return 0;
// }
// stringstream buffer;
// buffer << inFile.rdbuf();
// //change to file_string
// source = buffer.str();
lowerCaseString(source);
substitution(source, cipherKey, destination);
cout << destination << endl;
return 0;
}
//converts all letters that are upper case to lower case in source
string lowerCaseString(string &source)
{
unsigned i;
for(i = 0; i < source.size(); ++i)
{
if(isupper(source.at(i)))
{
source.at(i) = tolower(source.at(i));
}
}
return source;
}
//encrypts the source string based on the cipher key, then writes the encrypted string to string destination
bool substitution(string & source, string cipherKey, string &destination)
{
//the boolean function type is irrelevant to my error (I tried to run it with void type), I just have to return true or false if the
//string source is empty
//alphabet is used to compare to each value in source
string alphabet = "abcdefghijklmnopqrstuvwxyz";
unsigned i;
unsigned j;
//this for loop is probably unnecessary but I did it for the purpose of potential debugging
for(i = 0; i < source.size(); ++i)
{
destination.at(i) = source.at(i);
}
//if the string is empty
if(source.size() == 0)
{
return 0;
}
//if the string isn't empty
else
{
for(i = 0; i < source.size(); ++i)
{
for(j = 0; alphabet.at(j) == 'z'; ++j)
{
//if the current character in source is equal to a certain letter in the
//alphabet, write the corresponding value from the cipher key into destination
if(source.at(i) == alphabet.at(j))
{
destination.at(i) = cipherKey.at(j);
}
}
}
//changed this maybe change back
return 1;
}
}
Here is your substitution method working. The destination string was empty, causing the error :
bool substitution(string & source, string cipherKey, string &destination)
{
string alphabet = "abcdefghijklmnopqrstuvwxyz";
destination = source; // To make sure the size of destination is the same as source
if(source.size() == 0)
{
return false;
}
else
{
for(unsigned int i = 0; i < source.size(); ++i) // You can declare i and j in the loop if you want (in c++ not in c)
{
for(unsigned int j = 0; j < alphabet.size(); ++j) // way easier to use size instead of finding 'z'
{
if(source.at(i) == alphabet.at(j))
{
destination.at(i) = cipherKey.at(j);
}
}
}
return true;
}
}
Note that the character finding bit can be reduced to :
bool substitution(string & source, string cipherKey, string &destination)
{
string alphabet = "abcdefghijklmnopqrstuvwxyz";
destination = source; // To make sure the size of destination is the same as source
if(source.size() == 0)
return false;
else
{
for(unsigned int i = 0; i < source.size(); ++i)
destination.at(i) = cipherKey.at(alphabet.find(source.at(i)));
return true;
}
}
You were trying to access destination but it was empty. Try to avoid operating on particular indexes. It could be done like this:
void substituteCharacters(const std::string& source,
const std::string& cipherKey,
std::string& destination)
{
destination.reserve(source.size());//allocate memory once, so no allocation during push_backs
for(auto c : source)
destination.push_back(cipherKey[c-'a']);
}

Dynamic array of char* (or 2d dynamic array of chars)

I'm getting funky output when running this code. There isn't a compile error. As far as I can tell, the problem is in my getArgs(stringstream& ss, int size) function. The strings are not copying correctly into my char* variables. I wanted a dynamic array of char* to save my command line arguments to. What am I doing wrong here?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct arguments
{
int argc; //number of arguments
char **argv; //array of arguments
};
void startupMsg()
{
cout << "******** CS415 SHELL ********" << endl;
}
int countArgs(stringstream& ss)
{
string temp;
int count = 0;
while (ss >> temp)
{
count++;
}
return count;
}
char** getArgs(stringstream& ss, int size)
{
ss.clear();
ss.seekg(0, ios::beg);
char **ary = new char*[size];
for (int i = 0; i < size; i++)
ary[i] = new char;
int c = 0;
string temp;
while (ss >> temp)
{
ary[c] = const_cast<char*>(temp.c_str());
c++;
}
return ary;
}
void printArgs(arguments* args)
{
for (int i = 0; i < args->argc; i++)
{
cout << args->argv[i] << " ";
}
cout << endl;
}
arguments* parseCommand(string command)
{
arguments *args = new arguments;
stringstream ss(command);
args->argc = countArgs(ss);
args->argv = getArgs(ss, args->argc);
return args;
}
int main()
{
string command;
startupMsg();
//while(true)
//{
cout << "user#linux:~$ ";
getline(cin, command);
arguments *args = parseCommand(command);
cout << args->argc << endl;
printArgs(args);
//}
}
Your problem is here:
ary[c] = const_cast<char*>(temp.c_str());
A good rule of thumb is when you find yourself needing const_cast, you're probably doing something wrong. It's not like you never need it, but it's quite an exceptional thing.
In any case, what happens here? Okay, you read into ary[0] a pointer into temp's buffer. Now you get your next argument. Best case, ary[0] and ary[1] now point to the same argument and you've lost the first one. Worst case, temp had to reallocate and now ary[0] is already a dangling pointer.
Regardless, at the end of getArgs(), temp is destroyed, and now all your likely-not-even-different pointers are dangling.
That's bad. You'll need to come up with some different.

Trouble with struct() and arrays C++

So, i have to do this project for college. I have to write a program that manages the orders of a pizza restaurant. so far this is what i have done :
#include <iostream>
#include <array>
#include <string>
#include <cctype>
#include <cmath>
#include <locale>
#include <algorithm>
using namespace std;
const int MAX_INGREDIENTES_PIZZA=10;
const int MAX_PEDIDOS=20;
enum TIngrediente
{
TOMATE,
QUESO,
NATA,
CEBOLLA,
POLLO,
HUEVO,
SALAMI,
ANCHOA,
BACON,
GAMBA
};
struct TPedido
{
string nombre_cliente;
int telefono;
int numero_pedido;
int numero_ingredientes;
TIngrediente ingredientes;
};
typedef array<float, MAX_PEDIDOS> listado_pedidos;
const array<string, MAX_INGREDIENTES_PIZZA> TIngredientes2 = {{"tomate", "queso", "nata", "cebolla", "pollo", "huevo", "salami", "anchoa", "bacon", "gamba"}};
TIngrediente StrToIngrediente(string s);
string IngredienteTostr(TIngrediente c);
string tolower(string s);
string tolower(string s)
{
string r = s;
for (int i = 0; i < s.size(); ++i)
r[i] = tolower(r[i]);
return r;
}
TIngrediente StrToIngrediente(string s)
{
s=tolower(s);
int i;
while (i < TIngredientes2.size() and TIngredientes2[i] != s)
++i;
return (TIngrediente)i;
}
string IngredienteTostr(TIngrediente c)
{
return TIngredientes2[c];
}
TIngredientes2 leer_ingrediente()
{
TIngredientes2 r;
for (int i=0; i<MAX_INGREDIENTES_PIZZA;i++){
cin>>r[i];
r[i]=tolower(r[i]);
}
StrToIngrediente(TIngredientes2);
return r;
}
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
return s;
}
TPedido leer_pedido()
{
TPedido p;
string ingredientes;
bool ok=true;
getline (cin, p.nombre_cliente);
cin >> p.telefono;
cin >> p.numero_pedido;
cin >> p.numero_ingredientes;
cin.ignore(100,'\n');
//getline (cin, p.ingredientes);
StrToIngrediente(ingredientes);
//necesitamos inicializar la variable booleana
if( numero_ingredientes > MAX_INGREDIENTES_PIZZA)
ok=false;
else if (numero_pedido > MAX_PEDIDOS)
ok=false;
else if (ingredientes != TIngrediente[i])
ok=false;
return p;
}
OK, But im having a few issues :
1) i have declared TIngredientes2 as an array, but the compiler says to me Tingredientes2 does not name a type.
2) I have managed to write the functions that transforms String in TIngrediente (enum) and viceversa, but now i have to make 2 functions to read keyboard input/write in screen and i dunno how to use those functions. I have writen something below but i dont know if it is ok.
3) When it comes to read keyboard input in leer_pedido() i dont know if that is ok because of the struct and most important, i have no idea how to use the boolean to say if the data introduced is correct or not.
4) The next fuction consist in storing the data from the last fucntion leer_pedido() in a list, and i have no clue.
I hope someone can help me
1) Function can't return an object of type 'Ttingrediente2' if you haven't already made class of type 'Tingrediente2'.
In your function :
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
You're declaring variable 'Tingredientes s' and after it,you're printing it out on the screen but it hasn't got size (there are no elements inside s).
Try like this:
void escribir_ingrediente(array<string,MAX_INGREDIENTES_PIZZA> s)
{
for(int i=0; i<s.size(); i++)
cout<<s[i]<<endl;
}
where you are passing already existing array to a function and it's printing out elements of s array.
2) Just read more about enumerations,iterating over them and inserting new elements.
3) You're using boolean variable on the beginning of testing your user's input.Something like:
bool good_Input = true; // suppose user's input is ok
if( p.numero_ingredientes > MAX_INGREDIENTES_PIZZA || p.numero_pedido > MAX_PEDIDOS)
good_input=false; // input is not good if there is more ingredients than max number of ingredients
if(good_Input)
cout<<"Input is good"<<endl;
else cout << "Input is not good"<<endl;
Therefore,you are leading boolean variable through your code so if there may be a mistake,you change it's value to 'false' and it will be 'false' to the end so you will know how to handle it further in code.
4) Storing structure's data in vector is the most easiest way to do that:
vector<Tpedido> structuresVector;
sturcturesVector.push_back(leer_pedido());
leer_pedido function returns 'Tpedido' type so you can insert it in vector directly

Returning string from a function causing formatting issues

It's supposed to look like this: http://i.imgur.com/gko501E.png
Instead it looks like this: http://i.imgur.com/ISwqyD8.png
When I take the code out of the function and use it in the main class it works properly. However once I put it in this function the formatting problems occur, it also isn't filtering like it's supposed to. This program is supposed to take user input, store it in a string, remove all non-alphabetical characters, capitalize the vowels, and then space it out based on user defined variables given in the command line. It's also supposed to accept files as input in the command line, such as: 'program 5 8 < file'.
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
//make vowels uppercase
string filter(string input)
{
size_t found = input.find_first_of("aeiou");
while (found != string::npos)
{
if (islower(input[found]))
{
input[found] = toupper(input[found]);
found = input.find_first_of("aeiou", found + 1);
}
}
//Make consonants lowercase
size_t foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ");
while (foundLower != string::npos)
{
if (isupper(input[foundLower]))
{
input[foundLower] = tolower(input[foundLower]);
foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ", foundLower + 1);
}
}
//remove punctuation
for (int i = 0, len = input.size(); i < len; i++)
{
if (!isalnum(input[i]))
{
input.erase(i--, 1);
len = input.size();
}
}
return input;
}
int main(int argc, char* argv[])
{
int wordSize;
int wordSizeCounter;
int wordCounter = 0;
int rowSize;
//char letter;
wordSize = atoi(argv[1]);
rowSize = atoi(argv[2]);
ifstream inFile;
inFile.open(argv[3]);//open the input file
stringstream strStream;
strStream << inFile.rdbuf();//read the file
string test = strStream.str();//str holds the content of the file
if (!inFile) test = cin.get() ; // Read first character
//Begin filter for files
while (!test.empty())
{
filter(test);
if (test.length() < wordSize) //make sure we don't go out-of-bounds
{
wordSize = test.length();
}
cout << test.substr(0, wordSize);
cout << " ";
if (test.length() >= wordSize) //again, make sure we don't go out-of-bounds
{
test = test.substr(wordSize);
}
else
{
test = " ";
}
wordCounter++;
if (wordCounter == rowSize)
{
cout << std::endl;
wordCounter = 0;
}
if(test.empty())
{
test = cin.get();
}
}
cout << endl;
return 0;
}