So, I have tried and tried to make this c++ pig latin program, but it's just not working. Here is my code:
int main()
{
string tmp = "";
char a;
cout << "String: "; getline(cin, tmp);
char pigLatin[1024];
strncpy(pigLatin, tmp.c_str(), sizeof(pigLatin));
pigLatin[sizeof(pigLatin) - 1] = 0;
a = pigLatin[0];
pigLatin[sizeof(pigLatin)] = '-';
pigLatin[sizeof(pigLatin) + 1] = a;
pigLatin[sizeof(pigLatin) + 2] = 'a';
pigLatin[sizeof(pigLatin) + 3] = 'y';
for (int i = 1; i < sizeof(pigLatin); i++)
{
cout << pigLatin[i];
}
cout << endl;
system("PAUSE");
return 0;
}
When I run it, it doesn't return any runtime errors or anything, but when I enter a string it just puts the string minus the first letter and then a bunch of spaces. Does anyone know the problem?
The problem is that sizeof returns the size in bytes of the array not the length of the string it contains. In this case the result of sizeof is 1024 assuming char is 8 bits. You could always use strlen to determine the length of the string or you can eliminate the use of a naked array altogether and use std::string instead. This would decrease the size of your code significantly. Something like this...
int main()
{
cout << "String: " << flush;
string pigLatin;
getline(cin, pigLatin);
pigLatin += '-';
pigLatin += pigLatin[0];
pigLatin += "ay";
pigLatin.erase(0, 1);
cout << pigLatin << endl;
system("PAUSE");
}
Related
I need some help checking if the string is a space and then shifting it by one char in the Alphabet I can get the first word but not any after the space.
string Alphabet = "abcdefghijklmnogqrstuvwxyz ";
cout << "Enter your string > " << flush;
cin >> OldString;
int Length = OldString.length();
for (int i = 0; i < Length; i++) {
if(OldString[i] == Alphabet[26]){
NewString = NewString + Alphabet[26] ;
cout << "string found" << endl;
}
else {
Result = Alphabet.find(OldString[i], 0);
cout << Result << endl;
NewString = NewString + Alphabet[Result + 1];
}
}
cin is looking for the end of input string by searching for the first whitespace in the string.
You should rather use std::getline instead.
So your code is going to look like this:
#include <iostream>
#include <string>
std::string OldString;
string Alphabet = "abcdefghijklmnogqrstuvwxyz ";
cout << "Enter your string > " << flush;
std::getline(std::cin, OldString);
int Length = OldString.length();
for (int i = 0; i < Length; i++) {
if(OldString[i] == Alphabet[26]){
NewString = NewString + Alphabet[26] ;
cout << "string found" << endl;
}
else {
Result = Alphabet.find(OldString[i], 0);
cout << Result << endl;
NewString = NewString + Alphabet[Result + 1];
}
}
I am trying to find even length substrings from the string "000000".It worked fine till index 2 after that it's not producing desired output.My IDE was showing exception unhandled at line :str2=str1.substr(i,k);
#include <iostream>
#include<string>
using namespace std;
int main()
{
string str = "000000";
string str2, str1;
int i = 0;
while (i < str.length())
{
int k = 2;
str1 = str.substr(i);
cout << "\n new substring from " << i << " pos is ";
cout<<str1 << endl;
int len = str1.length();
cout << len << endl;
while (k <= len)
{
cout << "\n" << i << " " << k;
str2 = str1.substr(i, k);
cout << endl << str2;
k = k + 2;
str2.clear();
}
i++;
str1.clear();
}
}
It seems this statement
str2 = str1.substr(i, k);
^^^
does not make sense.
You mean
str2 = str1.substr(0, k);
^^^
I am trying to work out how I would be able to implement this autokey cipher and think that I have most of it worked out. The cipher is supposed to use a subkey style system using the characters positions in the alphabet.
Currently I am stuck on how to handle a few symbols " ;:,." when they are input as part of the encryption or decryption string and and not sure how to approach it as I am new to the language. Any guidance or direction would be wonderful. Posed the code and an example of how the cipher should work below.
Cipher Description:
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
//Declares
char autokeyE(int, int);
char autokeyD(char);
char numToLetter(int);
int letterToNum(char);
int main()
{
//Declares
string inputText, finalText;
int firstAlpha = 0;
int key = 0;
int option = 0;
//First Values
do
{
cout << "What operation would you like to do? Press '1' for Encrypt and '2' for Decrypt." << endl ;
cin >> option;
if (option == 1)
{
cout << "Please input your plain text to encrypt." << endl ;
cin >> inputText;
cout << "Please input your key to encrypt with." << endl;
cin >> key;
string finalText = "";
firstAlpha = letterToNum(inputText[0]);
finalText = numToLetter((firstAlpha + key) %26);
//inputText[0] = finalText[0];
for (int x = 1; x < inputText.length(); x++)
{
finalText += autokeyE(letterToNum(inputText[x-1]), letterToNum(inputText[x]));
}
cout << finalText << endl;
}
if (option == 2)
{
cout << "Please input your encrypted text to decrypt." << endl ;
cin >> inputText;
string finalText = "";
firstAlpha = letterToNum(inputText[0]);
finalText = numToLetter((firstAlpha + key) %26);
for (int x = 1; x < inputText.length(); x++)
{
//cout << inputText[x]; Testing output
finalText += autokeyD(inputText[x]);
}
cout << finalText << endl;
}
}
while (!inputText.length() == 0);
}
char autokeyE(int c, int n)
{
cout << "Keystream: " << n << " | Current Subkey: " << c << endl;
int result = 0;
//c = toupper(c);
result = ((c + n) +26 )%26;
cout << "C as a numtoletter: " << numToLetter(result) << " Result: " << result << endl;
return numToLetter(result);
return c;
}
char autokeyD(char c)
{
//Decrypting Shift -1
if (isalpha(c))
{
c = toupper(c);
c = (((c - 65) - 1) % 26) + 65;
}
return c;
}
char numToLetter(int n)
{
assert(n >= 1 && n <= 32);
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ ;:,."[n];
}
int letterToNum(char n)
{
if (isalpha(n))
{
n = toupper(n);
return(int) n - 65;
}
else
{
cout << "REUTRNING A NON ALPHA CHARACTER AS: " << n << endl;
return(int) n -30;
}
}
I don't understand your question, but I reckon the answer would be to do a back slash before each character that does not work, like so: "\;\:\,\." ( some of these may work, so only do it on the ones that don't)
You can handle symbols using isPunct in C++ such as:
if (isPunct(inputText[x]) {
//do whatever it is you need to do
}
I am doing the challenge from www.adventofcode.com/day/10
I have a code that i think works, I am using c++ just to get to learn while having fun.
I am doing the string manipulation recursive.
The problem here is that the program crashes with segmentation fault
on the line "char ch = line[0]" when doing more than 38 iterations.
#include <iostream>
#include <string>
using namespace std;
string count_chars(string line){
char ch = line[0];
uint i;
for(i = 0; ch == line[i]; i++){
}
if(i != line.length()){
line = to_string(i) + ch + count_chars(line.substr(i));
}
else{
line = to_string(i) + ch;
}
return line;
}
int main(int argc, char** args)
{
//ifstream in("dayx");
/*
if(argc ==1)
return 1;
string line;
cout << line.capacity() << endl;
line = args[1];
*/
string line = "1";
for(int i = 1; i < 40; i++){
line = count_chars(line);
//cout << line << " after " << i << " iterations" << endl;
cout <<"Line size: " << line.size() << endl;
}
cout << line << endl;
}
The code is compiled using:
g++ day10.cpp --std=c++11 -g
My questions, why is this happening, how can i prevent it and how can i use gdb to figure this out? Thanks!
I am using linux and gcc 5.3
You have stack overflow because of too deep recursion (several thousands calls deep). You could easily implement the algorithm using a loop instead.
I'm suspicious of any lines of code that access indices of a string that may not exist:
char ch = line[0];
uint i;
for(i = 0; ch == line[i]; i++){
}
if(i != line.length()){
line = to_string(i) + ch + count_chars(line.substr(i));
It grabs the first char from the string even if the string is empty.
It is only checking if i is the same as the length of the string - not if i is greater than the length of string.
**I can't use vectors, or any functions from the standard library with this program. Hence why I am writing it all myself.
Alright, this program is just about finished. All my user defined functions are working fine, except for the reverseCString function. When I run the program, and enter a string of "hello", I can select menu option "rev" to reverse the string. My main function then calls the reverseCString function, and uses the for loop in my main to print out my reversed c-string. The program works fine at this point, until the do-while loop continues..
After the rv function is called though, the program loops to continue to allow the user to modify their string, as it should. However, my c-string vanishes at this point. I can still operate on it if I use the other commands/funtions, but the c-string doesn't print to cout.
I don't understnad what is causing this, but I have isolated the problem down to the reverseCString function.
Here is my code so far:
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<string>
#include<math.h>
using namespace std;
void shiftLeft(char szString[], size_t shiftBy)
{
const char *p = szString;//
while (*p) ++p;//advance p to point to the the null terminator, found via personal research at http://stackoverflow.com/questions/12201815/what-difference-between-whilepp-while-p-and-whilep
size_t len = p - szString;//len is set to the size of our c-string
if (len > 1 && (shiftBy %= len))
{
char *ends[] = { szString+shiftBy, szString+len, szString+(len - shiftBy) };//create a temporary array for storage
for (size_t i = 0; i < 3; ++i)//use a for loop to flip the first three character
{
char *start = szString, *end = ends[i];
while (start < --end)//now flip the rest of the characters
{
char ch = *start;
*start++ = *end;
*end = ch;
}
}
}
}
void shiftRight (char szString[], int size, int shiftBy)
{
if(shiftBy > size){
shiftBy = shiftBy - size;
}
if(size == 1){
//do nothing, exit function with no change made to myarray
}
else{
char temp;
//for loop to print the array with indexes moved up (to the right) --> by 2
for (int i=0; i < size; i++)
{//EXAMPLE shift by 3 for a c-string of 5
temp = szString[size-shiftBy];//temp = myarray[2]
szString[size-shiftBy] = szString[i];//myarray[2] = myarray[i]
szString[i] = temp;//myarray[i] = temp(value previously at index 2)
}
}
}
void reverseCString(char szString[], const size_t& size){
char temp;
int i = 0;
int j = size-1;
//we can use a simple tep variable to flip everything
while(i < j)
{
temp = szString[i];
szString[i] = szString[j];
szString[j] = temp;
i++;
j--;
}
}
int main(){
string repeat = "";
string userInputString;
cout << "Please eneter your string: " << endl;
//cin >> ws;
getline(cin,userInputString);
char * szString = new char [userInputString.length()+1];
strcpy (szString, userInputString.c_str());
do {
cout << "Your c-string is: " << szString << endl;
string commandString = "";
cout << "Please enter a command: ";
getline(cin,commandString);
if (commandString[0] == 'L'){
cout << "You have chosen to shift your string left by " << commandString[1] << " characters." << endl;
const char * shiftLeftPtr = &commandString[1];
//convert this value to an int for our function
int shiftLeftBy = atoi(shiftLeftPtr);
//run our shifleft function
shiftLeft(szString,shiftLeftBy);
//print the results
cout << "Your c-string, shifted left by " << commandString[1] << endl;
cout << szString;
}
if (commandString[0] == 'R'){
cout << "You have chosen to shift your string right by " << commandString[1] << " characters." << endl;
const char * shiftRightPtr = &commandString[1];
//convert this value to an int for our function
int shiftRightBy = atoi(shiftRightPtr);
//run our shiftright function
shiftRight(szString,userInputString.length(),shiftRightBy);
//print the results
cout << "Your c-string, shifted right by " << commandString[1] << endl;
cout << szString;
}
if (commandString.compare("rev") == 0){
cout << "You have chosen to reverse your string. " << endl;
//run our reverseArray function
reverseCString(szString,userInputString.length()+1);
cout << "Your c-string, reversed: ";
for(int i = 0; i < userInputString.length()+1; i++){
///////////////////////////right her seems to be my issue
cout << szString[i];
}
}
if (!(commandString[0] == 'R' || commandString[0] == 'L' || commandString.compare("rev") == 0)){
cout << "You have entered an invalid selection." << endl;
}
cout << "\nEnter 'quit' to close the program, anything else to continue: ";
getline(cin,repeat);
}while(repeat.compare("quit") != 0);
return 0;
}
Your length logic is broken. Say the string contains "bar\0". You do this:
reverseCString(szString,userInputString.length()+1);
Now, length is 3, and you pass 4 to reverseCString. Then this happens:
void reverseCString(char szString[], const size_t& size){
char temp;
int i = 0;
int j = size-1;
Now, i is 0 and j is 3. So you swap items 0 and 3. Well, what are the items?
0 = b
1 = a
2 = r
3 = \0
When you swap items 0 and 3, you create a string that starts with a terminator, "\0rab". Of course printing that out won't produce anything.