CS50 substitution - Loop not working for length of plaintext - cs50

I am trying to create a loop for the length of the plaintext and converting the plaintext to alphabetic index so that i can get a pointer to the same location in argv[].However the loop only seems to be running for plain[0] and only getting the equivalent key for argv[0] (which is the key). Any help would be much appreciated.
string plain = get_string("plaintext: ");//prompt user for text
printf("ciphertext: ");
int lenp = strlen(plain);//get length of text
int c;
char* p;
for (int q = 0; q < lenp; q++)
{
if (isalpha(plain[q]))
{
if (isupper(plain[q]))
{
//covert from ASCII to alpabetic index
h = plain[q] - 65;
//pointer to the equivalent element in argv[]
p = &argv[1][h];
*p = argv[1][h];
c = *p;

Related

Swap two words in a char* using constant space in less than o(n^2) time

Given a char* to a string, say containing "hellosir", and the length's of each word,
how can I return a char* containg "sirhello" using constant space in less than o(n^2) time?
(I was asked this in an tech interview)
Function signature:
char* swapWords(char* str, int firstWordLen, int secondWordLen);
In the "hellosir" example firstWordLen is 5, and secondWordLen is 3.
Thanks
char* swapWords(char* str, int firstWordLen, int secondWordLen) {
char* newStr = (char*) malloc(sizeof(char) * (firstWordLen + secondWordLen + 1));
for(int i = 0; i < secondWordLen; i++) {
newStr[i] = str[firstWordLen + i];
}
for(int i = 0; i < firstWordLen; i++) {
newStr[secondWordLen + i] = str[i];
}
newStr[firstWordLen + secondWordLen] = 0;
return newStr;
}
Explanation:
Loop over the second word, it starts at the end of word one, so firstWordLen + i, and place the chars at the beginning of the new char array
Loop over the first word, so from 0 to firstWordLen and place it at the end of the previously placed second word, so at secondWordLen + i
Add 0 to the end of the new char array because of null termination
Ah ok, this is not constant space my bad, the speed is O(n), but the space is also O(n)

Caesar problem code generating "error: implicitly declaring library function 'strlen' with type 'unsigned long (const char *)'

I am doing the CS50 course and am on week 2. One of the problems of week 2 is called "Caesar". Essentially you have to write code which cyphers text by shifting letters that use the users inputted preferred number. After running my code I keep getting this error
"error: implicitly declaring library function 'strlen' with
type 'unsigned long (const char *)'
[-Werror,-Wimplicit-function-declaration]
for(i = 0, l = strlen(text); i < n; i++)"
This is the code:
int main(int argc, string argv[])
{
string n = argv[1];
int y = argc;
int key = get_int("./caesar ");//getting the number from the user
int k = (key);//assigning key a variable name.
string text = get_string("plaintext: ");//letting the user input their text.
if (key < 1)//Trying to make limit for acceptable input.
{
printf("ERROR");
return 1;
}
int l;
int i;
//for loop containing the encipher process
for(i = 0, l = strlen(text); i < n; i++)
{
if(isalpha(i))
{
if (isupper[i])
{
printf("ciphertext: %c",(text[i] + k)%26 + 65);
}
else (islower[i])
{
printf("ciphertext: %c",(text[i] + k)%26 + 65);
}
}
}
printf("ciphertext: %c", d || c);
return;
int checking_key(int y,string n)
int num = argc;
string key = y;
int num_key = atoi(key);
if(argc != 2)
{
return 0;
}
else
{
if (num_key > 0)
{
return num_key;
}
else
{
return 0;
}
}
}
From man strlen:
Synopsis
#include <string.h>
size_t strlen(const char *s);
Just like one needs to "include" cs50.h to use any of the get_* functions, string.h must be "include"d to access its functions, eg strlen.
Additionally (per comments):
The "ordered comparison" in the compile error
ordered comparison between pointer and integer ('int' and 'string' (aka 'char *')) [-Werror] for(i = 0, l = strlen(text); i < n; i++)
is i < n. Error says one of them is an int and one of them is a string.
On closer inspection this program is a long way from a clean compile. Recommend you follow along with the spec and "approach this problem one step at a time"

String to Int Conversion in Arduino

I' am trying to convert string to int(like Integer.parseInt() in java) in arduino in order to make some operation's on the numbers. Unfortunately none of my solution's worked.
Until now I tried:
Create char Array and call atoi function:
String StringPassword;
uint8_t *hash;
//Here I define hash
int j;
for (j = 0; j < 20; ++j) {
StringPassword.concat(hash[j]);
}
//Checking String Size
Serial.println("Size");
//Checking String
Serial.println(StringPassword.length());
Serial.println(StringPassword);
int jj;
char PasswordCharArray[StringPassword.length()];
StringPassword.toCharArray(PasswordCharArray, StringPassword.length());
awa = atoi(PasswordCharArray);
Serial.println(awa);
Output:
Size
48
168179819314217391617011617743249832108225513297
18209
Create char Array for null terminated string and call atoi function:
String StringPassword;
uint8_t *hash;
//Here I define hash
int j;
for (j = 0; j < 20; ++j) {
StringPassword.concat(hash[j]);
}
//Checking String Size
Serial.println("Size");
//Checking String
Serial.println(StringPassword.length());
Serial.println(StringPassword);
int jj;
char PasswordCharArray[StringPassword.length()+1];
StringPassword.toCharArray(PasswordCharArray,StringPassword.length()+1);
awa = atoi(PasswordCharArray);
Serial.println(awa);
Output:
Size
48
168179819314217391617011617743249832108225513297
-14511
use toInt Function:
String StringPassword;
uint8_t *hash;
//Here I define hash
int j;
for (j = 0; j < 20; ++j) {
StringPassword.concat(hash[j]);
}
//Checking String Size
Serial.println("Size");
//Checking String
Serial.println(StringPassword.length());
Serial.println(StringPassword);
awa = StringPassword.toInt();
Serial.println(awa);
Output:
Size
48
168179819314217391617011617743249832108225513297
-14511
What is the proper way of changing String to Int so:
awa = 168179819314217391617011617743249832108225513297 ?
And could someone explain to me why my solution's didn't worked? I tried to use the function's that were mentioned on Stackoverflow and Arduino forum to solve this.
The number 168179819314217391617011617743249832108225513297 reaches the maximum integer value limit so therefore this will not convert into an integer.
Try using atol() instead of atoi(). Long numbers can hold more data like the number shown above.

Brute-force transposition decryption - word segmentation

I'm a 2nd year B. Comp. Sci. student and have a cryptography assignment that's really giving me grief. We've been given a text file of transposition-encrypted English phrases and an English dictionary file, then asked to write a program that deciphers the phrases automatically without any user input.
My first idea was to simply brute-force all possible permutations of the ciphertext, which should be trivial. However, I then have to decide which one is the most-likely to be the actual plaintext, and this is what I'm struggling with.
There's heaps of information on word segmentation here on SO, including this and this amongst other posts. Using this information and what I've already learned at uni, here's what I have so far:
string DecryptTransposition(const string& cipher, const string& dict)
{
vector<string> plain;
int sz = cipher.size();
int maxCols = ceil(sz / 2.0f);
int maxVotes = 0, key = 0;
// Iterate through all possible no.'s of cols.
for (int c = 2; c <= maxCols; c++)
{
int r = sz / c; // No. of complete rows if c is no. of cols.
int e = sz % c; // No. of extra letters if c is no. of cols.
string cipherCpy(cipher);
vector<string> table;
table.assign(r, string(c, ' '));
if (e > 0) table.push_back(string(e, ' '));
for (int y = 0; y < c; y++)
{
for (int x = 0; x <= r; x++)
{
if (x == r && e-- < 1) break;
table[x][y] = cipherCpy[0];
cipherCpy.erase(0, 1);
}
}
plain.push_back(accumulate(table.begin(),
table.end(), string("")));
// plain.back() now points to the plaintext
// generated from cipher with key = c
int votes = 0;
for (int i = 0, j = 2; (i + j) <= sz; )
{
string word = plain.back().substr(i, j);
if (dict.find('\n' + word + '\n') == string::npos) j++;
else
{
votes++;
i += j;
j = 2;
}
}
if (votes > maxVotes)
{
maxVotes = votes;
key = c;
}
}
return plain[key - 2]; // Minus 2 since we started from 2
}
There are two main problems with this algorithm:
It is incredibly slow, taking ~30 sec. to decrypt a 80-char. message.
It isn't completely accurate (I'd elaborate on this if I hadn't already taken up a whole page, but you can try it for yourself with the full VC++ 2012 project).
Any suggestions on how I could improve this algorithm would be greatly appreciated. MTIA :-)

Converting a 1D pointer array (char) into a 2D pointer array (char) in Visual C++.

I am new to c++ programming I have to call a function with following arguments.
int Start (int argc, char **argv).
When I try to call the above function with the code below I get run time exceptions. Can some one help me out in resolving the above problem.
char * filename=NULL;
char **Argument1=NULL;
int Argument=0;
int j = 0;
int k = 0;
int i=0;
int Arg()
{
filename = "Globuss -dc bird.jpg\0";
for(i=0;filename[i]!=NULL;i++)
{
if ((const char *)filename[i]!=" ")
{
Argument1[j][k++] = NULL; // Here I get An unhandled
// exception of type
//'System.NullReferenceException'
// occurred
j++;
k=0;
}
else
{
(const char )Argument1[j][k] = filename [j]; // Here I also i get exception
k++;
Argument++;
}
}
Argument ++;
return 0;
}
Start (Argument,Argument1);
Two things:
char **Argument1=NULL;
This is pointer to pointer, You need to allocate it with some space in memory.
*Argument1 = new char[10];
for(i=0, i<10; ++i) Argument[i] = new char();
Don't forget to delete in the same style.
You appear to have no allocated any memory to you arrays, you just have a NULL pointer
char * filename=NULL;
char **Argument1=NULL;
int Argument=0;
int j = 0;
int k = 0;
int i=0;
int Arg()
{
filename = "Globuss -dc bird.jpg\0";
//I dont' know why you have 2D here, you are going to need to allocate
//sizes for both parts of the 2D array
**Argument1 = new char *[TotalFileNames];
for(int x = 0; x < TotalFileNames; x++)
Argument1[x] = new char[SIZE_OF_WHAT_YOU_NEED];
for(i=0;filename[i]!=NULL;i++)
{
if ((const char *)filename[i]!=" ")
{
Argument1[j][k++] = NULL; // Here I get An unhandled
// exception of type
//'System.NullReferenceException'
// occurred
j++;
k=0;
}
else
{
(const char )Argument1[j][k] = filename [j]; // Here I also i get exception
k++;
Argument++;
}
}
Argument ++;
return 0;
}
The first thing you have to do is to find the number of the strings you will have. Thats easy done with something like:
int len = strlen(filename);
int numwords = 1;
for(i = 0; i < len; i++) {
if(filename[i] == ' ') {
numwords++;
// eating up all spaces to not count following ' '
// dont checking if i exceeds len, because it will auto-stop at '\0'
while(filename[i] == ' ') i++;
}
}
In the above code i assume there will be at least one word in the filename (i.e. it wont be an empty string).
Now you can allocate memory for Argument1.
Argument1 = new char *[numwords];
After that you have two options:
use strtok (http://www.cplusplus.com/reference/clibrary/cstring/strtok/)
implement your function to split a string
That can be done like this:
int i,cur,last;
for(i = last = cur = 0; cur < len; cur++) {
while(filename[last] == ' ') { // last should never be ' '
last++;
}
if(filename[cur] == ' ') {
if(last < cur) {
Argument1[i] = new char[cur-last+1]; // +1 for string termination '\0'
strncpy(Argument1[i], &filename[last], cur-last);
last = cur;
}
}
}
The above code is not optimized, i just tried to make it as easy as possible to understand.
I also did not test it, but it should work. Assumptions i made:
string is null terminated
there is at least 1 word in the string.
Also whenever im referring to a string, i mean a char array :P
Some mistakes i noticed in your code:
in c/c++ " " is a pointer to a const char array which contains a space.
If you compare it with another " " you will compare the pointers to them. They may (and probably will) be different. Use strcmp (http://www.cplusplus.com/reference/clibrary/cstring/strcmp/) for that.
You should learn how to allocate dynamically memory. In c you can do it with malloc, in c++ with malloc and new (better use new instead of malloc).
Hope i helped!
PS if there is an error in my code tell me and ill fix it.

Resources