Caesar Cipher using char * ? c++ - c++

So i am trying to use the Ceasar Cipher with char *'s, I've written a simple function out like this:
char * Encrypt(char * s, int k)
{
char * c = s;
for(int i = 0; i < strlen(s); i++)
c[i] += k;
return c;
}
that seems to look like it should work but it doesn't. It throws an error when running program.
Here is an example of how i call this function:
int main()
{
cout << Encrypt("hello", 2) << endl;
system("pause");
return 0;
}
And before you say "why not just use string?", well the answer is I'm writing C++ on a certain SDK that causes compiler errors when using string. Ok but yeah, any form of help will greatly be appreciated, thanks!

String literals like "Hello" are read only. If you try to modify such a string you will have undefined behavior.
In C++ string literals are actually arrays of constant characters.
Using char* to access a string literal should have your compiler to scream a warning at you. If not you need to turn up your warning level or enable more warnings.
If you're really programming in C++ I suggest you learn about std::string and find a good beginners book to read.

Related

Passing the char *str inside the function

I newly started C++ and it feels pretty wired while writing Java for a while. So, I have this array,
char values[][10] = {"miami", "seattle", "berlin"};
int rows = sizeof values / sizeof values[0];
This is this is the function where I would like to pass the value,
// a function to reverse the strings
void App::reverse(char *str) {
}
When I do the loop, I can't apparently pass the value there,
for (int i = 0; i < rows; ++i) {
// first character of the string
char *firstPtr = values[i];
reverse(firstPtr);
}
The line reverse(firstPtr) provides error which I don't understand. The error message says Too few arguments, expected 2.
What is the issue here? I apologize for any mistakes as writing the C++ for the first time and the pointer stuff feels strange.
UPDATE
This is the piece of code I would like to exexute,
void App::reverse(char* str) {
// get the first character of the string
char *ptrEnd = str;
char temp;
if (str){
while (*ptrEnd) {
ptrEnd++;
}
ptrEnd--;
// as long the first adddress is lesser than the end
while (str < ptrEnd) {
temp = *str;
*str++ = *ptrEnd;
*ptrEnd-- = temp;
}
}
}
There is too little information here to be sure, but it looks like you have
using namespace std;
Somewhere in your code. Don't do this! In this case, the standard library has a function reverse() in std that takes two parameters.
Furthermore, you have void App::reverse(char *str), but that cannot be seen from void myArray::reverse(char* str), so your own reverse() cannot be called as-is - you would need to do App::reverse() if the function is a class static.

Scanning ASCII value of each character of a string

Is there anyway , if I enter any string , then I want to scan ASCII value of each character inside that string , if I enter "john" then I should get 4 variables getting ASCII value of each character, in C or C++
Given a string in C:
char s[] = "john";
or in C++:
std::string s = "john";
s[0] gives the numeric value of the first character, s[1] the second an so on.
If your computer uses an ASCII representation of characters (which it does, unless it's something very unusual), then these values are the ASCII codes. You can display these values numerically:
printf("%d", s[0]); // in C
std::cout << static_cast<int>(s[0]); // in C++
Being an integer type (char), you can also assign these values to variables and perform arithmetic on them, if that's what you want.
I'm not quite sure what you mean by "scan". If you're asking how to iterate over the string to process each character in turn, then in C it's:
for (char const * p = s; *p; ++p) {
// Do something with the character value *p
}
and in (modern) C++:
for (char c : s) {
// Do something with the character value c
}
If you're asking how to read the string as a line of input from the terminal, then in C it's
char s[SOME_SIZE_YOU_HOPE_IS_LARGE_ENOUGH];
fgets(s, sizeof s, stdin);
and in C++ it's
std::string s;
std::cin >> s; // if you want a single word
std::getline(std::cin, s); // if you want a whole line
If you mean something else by "scan", then please clarify.
You can simply get the ascii value of a char by casting it to type int:
char c = 'b';
int i = c; //i contains ascii value of char 'b'
Thus, in your example the code to get the ascii values of a string would look something like this:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string text = "John";
for (int i = 0; i < text.size(); i++)
{
cout << (int)text[i] << endl; //prints corresponding ascii values (one per line)
}
}
To get the corresponding char from an integer representing an entry in the ascii table, you just have to cast the int back to char again:
char c = (char)74 // c contains 'J'
The code given above was written in C++ but it basically works the same way in C (and many other languages as well I guess)
There is no way to turn a string of length 'x' into x variables. In C or C++ you can only declare a fixed number of variables. But probably you don't need to do what you are saying. Perhaps you just need an array, or most likely you just need a better way to solve whatever problem you are trying to solve. If you explain what the problem is in the first place, then I'm sure a better way can be explained.
Ya,I think there are some more better solutions are also available but this one also be helpful.
In C
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(){
char s[]="abc";
int cnt=0;
while(1){
if(s[cnt++]==NULL)break;
}
int *a=(int *)malloc(sizeof(int)*cnt);
for(int i=0;i<cnt;i++)a[i]=s[i];
for(int i=0;i<cnt-1;i++)printf("%d\n",a[i]);
return 0;
}
In C++
#include <iostream>
#include <string>
using namespace std;
int main(){
string s="abc";
//int *a=new int[s.length()];
//for(int i=0;i<s.length();i++)a[i]=s[i];
for(int i=0;i<s.length();i++)
cout<<(int)s[i]<<endl;
return 0;
}
I hope this one will be helpful..
yeah it's very easy ..just a demo
int main()
{
char *s="hello";
while(*s!='\0')
{
printf("%c --> %d\n",*s,*s);
s++;
}
return 0;
}
But make sure your machine is supporting the ASCII value format.
In C every char has one integral value associted with it called ASCII.
Using %d format specifier you can directly print the ASCII of any char as above.
NOTE: It's better to get good book and practice this kind of program yourself.

Convert vector<string> * char to int

I need help in my following code and hope that you can help me through. All I wanted is to pass in INT type to setX() and setY(). However, there is no way for me to convert vector char* to int. Is there alternative to this?
template<class T>
vector<string> Delimiter(T inputString){
int count=0;
char str[inputString.length()];
strcpy(str,inputString.c_str());
char * pch;
vector<string> returnContainer;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,",[]");
while (pch != NULL)
{
returnContainer.push_back(pch);
pch = strtok (NULL, " ,[]");
count++;
}
for(int i=0; i<returnContainer.size(); i++){
cout << "return:" << returnContainer[i] << endl;
}
return returnContainer;
}
//Main()
fileDataAfterFiltered = Delimiter(fileData[i]); // Delimiter (vector<string> type)
point2DObj[point2DCount].setX(fileDataAfterFiltered[1]); // error
point2DObj[point2DCount].setY(fileDataAfterFiltered[2]); // error
//Assn3.cpp:107:59: error: no matching function for call to ‘Point2D::setX(std::basic_string&)’
Delimiter() returns a vector<string> and you give one of these strings to setX() and setY(), but both expect an integer parameter. You must convert the string to int
int x = atoi(fileDataAfterFiltered[1].c_str());
point2DObj[point2DCount].setX(x);
int y = atoi(fileDataAfterFiltered[2].c_str());
point2DObj[point2DCount].setY(y);
But: in C++ array and vector elements start at 0 not 1, so you might want to replace this with fileDataAfterFiltered[0] and fileDataAfterFiltered[1] respectively.
If you are using a C++11 compiler, function std::stoi() will do the trick:
point2DObj[point2DCount].setX(std::stoi(fileDataAfterFiltered[1]));
Otherwise you can use the old atoi():
point2DObj[point2DCount].setX(atoi(fileDataAfterFiltered[1].c_str()));
Aside from this, your code has many other problems, but I hope you can fix them by yourself.
there's plenty of ways of converting string to int. boost::lexical_cast is one which will magically do the conversion you want. Otherwise you can use atoi (if you don't care about errors), or strtol (if you do).
point2DObj[point2DCount].setX(atoi(fileDataAfterFiltered[1].c_str()));
point2DObj[point2DCount].setX(boost::lexical_cast<int>(fileDataAfterFiltered[1]));

strchr not working with char[]

I am working on ROT13 for c++ practice. however this bit of code here returns an error and fails to compile, i do not understand why! I am posting a snippet of code in the following lines
string encode(string &x)
{
char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
for (size_t l=0;l<x.size();++l){
cout<<x[l];
cout<< strchr(alphabet,x[l]);
}
return x;
}
Q2. Also help me return the index of the matching letter from alphabet[] (e.g.,5 for 'f') to which i can add 13 and append that to x and so on ..
Q3. Besides practice, which course in CS would help me develop more efficient algorithms? Is it theory of computation, discrete mathematics, or algorithms ?
In order, starting with question 1:
The following compiles fine for me:
#include <iostream>
#include <cstring>
std::string encode(std::string &x)
{
char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
char *ptr;
for (size_t l=0;l<x.size();++l){
std::cout<<x[l];
std::cout<< std::strchr(alphabet,x[l]);
}
return x;
}
int main (int argc, char* argv []) {
return 0;
}
Make sure:
you include the headers given, for cout and strchr.
use std:: prefixes unless you're using the std namespace.
fix that ptr problem.
Question 2:
If you're looking for a handy ROT-13 method, consider using two C strings, one for the source and one for the translation:
char from[] = "abcdefghijklmnopqrstuvwxyz";
char to [] = "nopqrstuvwxyzabcdefghijklm";
Then you can use strchr to look it up in the first one and use that pointer to find the equivalent in the second.
char src = 'j';
char *p = strchr (from, src);
if (p == NULL)
std::cout << src;
else
std::cout << to[p - from];
That would output the character as-is if it wasn't found or look up the translation if it was found. You may also want to put the capital letters in there as well.
Question 3:
If you want to learn about efficient algorithms, I'd go for, surprisingly enough, an algorithms course :-)
Theory of computation sounds a little dry, though it may well cover the theoretical basis behind algorithms. Discrete mathematics has applicability to algorithms but, again, it's probably very theoretical. That's all based on what the words mean, of course, the actual subject areas covered may be totally different, so you should probably take it up with the people offering the courses.
Extra bit:
If you're looking for something to compare your own work to, here's one I put together based on my suggestions above:
#include <iostream>
#include <cstring>
std::string rot13 (std::string x)
{
char from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char to [] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
std::string retstr = "";
for (size_t i = 0; i < x.size(); ++i) {
char *p = std::strchr (from, x[i]);
if (p == 0)
retstr += x[i];
else
retstr += to[p - from];
}
return retstr;
}
int main (int argc, char* argv []) {
std::string one = "This string contains 47 and 53.";
std::string two = rot13 (one);
std::string three = rot13 (two);
std::cout << one << '\n';
std::cout << two << '\n';
std::cout << three << '\n';
return 0;
}
The building of the return string could have probably been done more efficiently (such as a new'ed character array which becomes a string only at the end) but it illustrates the "lookup" part of the method well.
The output is:
This string contains 47 and 53.
Guvf fgevat pbagnvaf 47 naq 53.
This string contains 47 and 53.
which you can verify here, if necessary.
Cast alphabet to a const char*, it should work afterwards. Keep in mind that type[] is different from type *.

Error when running g++ app. (encryption of string)

I'm trying to encrypt and decrypt files with C++, using this code:
#include <iostream>
void crypt(char* pData, unsigned int lenData, const char* pKey, unsigned int lenKey)
{
for (unsigned int i = 0; i < lenData; i++)
pData[i] = pData[i] ^ pKey[i % lenKey];
}
int main()
{
char* data = (char*)"any binary string here";
crypt(data, 22, "key", 3);
std::cout << data;
}
I'm compiling with g++ (tdm-1) 4.5.1 (MinGW) on Windows 6.1 (Seven), it compiles with no errors or warnings. When I try to run, it shows a window with "app.exe stoped working. The Windows can check online if there has some solution to the problem." (some thing like that, my Windows isn't in English). I don't have any idea about what is wrong.
You're trying to modify a string constant. For obvious reasons (it's constant), this won't work. Instead, do this:
int main()
{
char data[] = "any binary string here";
crypt(data, 22, "key", 3);
std::cout << data;
}
This line is wrong:
char* data = (char*)"any binary string here";
First, you should not use a cast. Next, a string literal is a constant. So it should be:
const char* data = "any binary string here";
But you're wanting to overwrite it. So you need a string that isn't a constant. Like this:
char data[] = "any binary string here";
Mike has answered this question well. You cannot modify constant string literals. Time of DOS has almost ended. Proper up-to-date production level C++ compiler should have issued a warning with appropriate flags. Just to add a little bit to the Mike's answer, here is a good explanation of constant string literals - http://msdn.microsoft.com/en-us/library/69ze775t(v=vs.80).aspx
Also, here is the better way to do it:
#include <iostream>
void crypt(char* pData, unsigned int lenData, const char* pKey, unsigned int lenKey)
{
for (unsigned int i = 0; i < lenData; ++i)
pData[i] ^= pKey[i % lenKey];
}
int main()
{
char data[] = "any binary string here";
const char key[] = "key";
crypt (data, sizeof(data) - 1, key, sizeof (key) - 1);
std::cout << data << std::endl;
}
Note post-increment operator, ^= and sizeof operators. For simple types compiler will do this micro-optimization for you, but developing a good habit is good. If you have a complex iterator, using post-increment can harm you on performance critical paths. Also, hardcoding size of strings is error-prone. Later you or someone else can change the string and forget to change its length. Not to mention that every time you have to go and count number of characters.
Happy coding!