#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char * argv[]) {
srand(time(NULL));
if (argc < 1) {
cout << "Too few arguments inserted.\nUSAGE: RKRIPT [InFile] [OutFile]" << endl;
return EXIT_FAILURE;
}
string InFile, OutFile;
InFile = argv[1];
OutFile = argv[2];
if (InFile.size() > FILENAME_MAX || OutFile.size() > FILENAME_MAX) {
cout << "Invalid filename lenght.\nFILENAME_MAX = " << FILENAME_MAX;
return EXIT_FAILURE;
}
wstring * Cont = new wstring;
if (Cont == nullptr) {
cout << "Memory allocation failed." << endl;
return EXIT_FAILURE;
}
wifstream i_f;
wchar_t temp;
i_f.open(InFile);
while (i_f.get(temp)) {
*Cont += temp;
}
i_f.close();
wofstream o_f;
o_f.open(OutFile);
long long int OutSize = 0;
for (long long int i = 0; i < Cont->size(); i++) {
do {
temp = wchar_t(rand() % WCHAR_MAX); //Keeps getting another value for temp until its sum with the current character doesn't exceed WCHAR_MAX.
} while (((long long int)temp + (long long int)Cont->at(i)) > WCHAR_MAX);
o_f << temp + Cont->at(i) << temp;
OutSize += 2;
}
o_f.close();
cout << "Done. Input file was " << InFile << "(" << Cont->size() << " Bytes)" << ". Output file is " << OutFile << "(" << OutSize << " Bytes)";
delete Cont;
return EXIT_SUCCESS;
}
This code is a simple "encrypter" that plays with altcodes to conceal characters. Though, when the application is done, the output file will be empty. The file output file I specified isn't anywhere at all. This application is meant to be run from shell. So, say I want to encrypt dummy.txt, I'll have to use this:RKRIPT dummy.txt out.txt.
At first I thought that I was using the stream incorrectly, leading to characters not to be printed out. But after changing
for (long long int i = 0; i < Cont->size(); i++) {
do {
temp = wchar_t(rand() % WCHAR_MAX); //Keeps getting another value for temp until its sum with the current character doesn't exceed WCHAR_MAX.
} while (((long long int)temp + (long long int)Cont->at(i)) > WCHAR_MAX);
o_f << temp + Cont->at(i) << temp;
OutSize += 2;
}
to this(notice the changes from WCHAR_MAX to CHAR_MAX)...
for (long long int i = 0; i < Cont->size(); i++) {
do {
temp = wchar_t(rand() % WCHAR_MAX); //Keeps getting another value for temp until its sum with the current character doesn't exceed CHAR_MAX.
} while (((long long int)temp + (long long int)Cont->at(i)) > CHAR_MAX);
o_f << temp + Cont->at(i) << temp;
OutSize += 2;
}
My output was just fine, because there were only narrow characters(ASCII) to write on my file. Though, I don't know how to fix this, how do I get my WIDE characters to be written onto a file using a WIDE stream? Thanks for any reply.
Related
So I have an array of symbols which has another array of symbols in it (if i'm not wrong). What I need to do is to change third element (words[2]). This third element will definitely be a number. I have to increase this number by 15 percent. Therefore, I need to convert words[2] to int?
Function:
void create(char* str) {
char** words = new char* [strlen(str)];
int count = 0;
for (char* part = strtok(str, " "); part != NULL; part = strtok(NULL, " ")) {
words[count] = _strdup(part);
count++;
}
cout << "\nNew sentence with edited values:" << endl;
words[2] = words[2] + ((int)words[2] / 100) * 15; //the main problem as I guess
for (int i = 0; i < count; i++) {
printf("%s ", words[i]);
}
cout << endl;
delete[] words;
}
Full code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <conio.h>
#include <string.h>
using namespace std;
void create(char*);
void main() {
const int maxLength = 100;
char* str = new char[maxLength];
cout << "Enter sentence:\n";
cin.getline(str, maxLength);
create(str);
delete[] str;
}
void create(char* str) {
char** words = new char* [strlen(str)];
int count = 0;
for (char* part = strtok(str, " "); part != NULL; part = strtok(NULL, " ")) {
words[count] = _strdup(part);
count++;
}
cout << "\nNew sentence with edited values:" << endl;
words[2] = words[2] + ((int)words[2] / 100) * 15;
for (int i = 0; i < count; i++) {
printf("%s ", words[i]);
}
cout << endl;
delete[] words;
}
What it needs to look like (3rd element increased by 15 percent):
Cannot do this using string. Actually, it is my homework from a university and not using string is the condition
you need to convert a char* to int like below. (int) casting won't work
int a = atoi(words[2]); // make sure words[2] is null terminated
This code should read a .pnm file. I tried to run it with 2 resolutions:
200x200 px: Here everything works just fine.
500x281 px: Code instantly crashes, raising a SIGSEGV error.
As far as I know, SIGSEGV is related to memory issues. I have 8GB of RAM, a quantity that I judge to be enough to run this. I don't have any idea about why it's happening and how to fix it.
Code
#define IO_ERROR (5)
#define X_DIMENSION (500)
#define Y_DIMENSION (281)
#define C_DIMENSION (3)
#define HEADER_SIZE (3)
#define BODY_SIZE (X_DIMENSION * Y_DIMENSION * C_DIMENSION)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int readImage(string fileName, string *imgHeader, string *imgBody)
{
ifstream inputFile(fileName);
if (!inputFile.is_open())
return IO_ERROR;
string line;
int count = 0;
while (getline(inputFile, line)) {
if (line.find("#") != string::npos)
continue;
if (count < 3)
imgHeader[count] = line;
else
imgBody[count - HEADER_SIZE] = line;
count++;
}
inputFile.close();
return 0;
}
void numericParser(const string *imgBody, unsigned char *numericBody)
{
int i = 0;
while(i < BODY_SIZE) {
numericBody[i] = (unsigned) atoi(imgBody[i].c_str());
i++;
}
}
void rgbParser(const string *imgBody, unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION])
{
unsigned char numericBody[BODY_SIZE];
numericParser(imgBody, numericBody);
int k = 0;
for (int i = 0; i < X_DIMENSION; i++) {
for (int j = 0; j < Y_DIMENSION; j++) {
for (int c = 0; c < 3; c++) {
rgbMatrix[i][j][c] = numericBody[k];
k++;
}
}
}
}
void printInfo(const string *header, const string *body)
{
cout << "#-*- Image Header -*-" << endl;
for (int i = 0; i < HEADER_SIZE; i++) {
cout << header[i] << endl;
}
cout << "#-*- Image Body -*-";
for (int i = 0; i < 5 * C_DIMENSION; i++) {
if (i % 3 == 0) cout << endl << "R: " << body[i];
else if (i % 3 == 1) cout << " G: " << body[i];
else cout << " B: " << body[i];
}
cout << endl << ". . ." << endl;
}
int main()
{
string fileName;
cout << "File name: ";
cin >> fileName;
string imgHeader[HEADER_SIZE];
string imgBody[BODY_SIZE];
if(readImage(fileName, imgHeader, imgBody) == IO_ERROR)
return IO_ERROR;
// printInfo(imageData);
unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION];
rgbParser(imgBody, rgbMatrix);
return 0;
}
Additional Info
I'm on Arch Linux 64-bit, using CLion as IDE.
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 have to write a code that compares three text files and i cant for the life of me find out why this wont print anything:
#include <iostream>
#include <cstring>
#include <string>
#include <fstream>
using namespace std;
int main (int argc, char *argv[])
{
ifstream mousefile;
mousefile.open(argv[1]);
string mouse_dna;
getline(mousefile, mouse_dna);
ifstream humanfile;
humanfile.open(argv[2]);
string human_dna;
getline(humanfile, human_dna);
ifstream unknownfile;
unknownfile.open(argv[3]);
string unknown_dna;
getline(unknownfile, unknown_dna);
int len = mouse_dna.size();
int mouseDistance = 0, humanDistance = 0;
for(int i=0; i<len; i++)
if(mouse_dna[i] != unknown_dna[i])
mouseDistance++;
return mouseDistance;
for(int i=0; i<len; i++)
if(human_dna[i] != unknown_dna[i])
humanDistance++;
return humanDistance;
double similarity_scoreH = (len - humanDistance) / len;
double similarity_scoreM = (len - mouseDistance) / len;
cout << "MouseCompare = " << similarity_scoreM << endl;
cout << "HumanCompare = " << similarity_scoreH << endl;
if (similarity_scoreH == similarity_scoreM)
cout << "identity cannot be determined" << endl;
else if (similarity_scoreH > similarity_scoreM)
cout << "human" << endl;
else if (similarity_scoreM > similarity_scoreH)
cout << "mouse" << endl;
}
It compiles properly, and doesn't give any errors, but when i rut it as:
./DNA mouseDNA.txt humanDNA.txt unknownDNA.txt
it still does nothing.
I appreciate any help. Thanks!
It doesn't print anything because it's returning before the instructions to print (return mouseDistance; or return humanDistance;). Make your function more verbose by printing progress messsages before each return statement.
As already has pointed out, you return too early. I modify your code:
I put brackets around the if block and for block.
I have a return statement at the end.
This is a start. You may have to add more checking, for example, if the file is open correctly.
#include <iostream>
#include <cstring>
#include <string>
#include <fstream>
using namespace std;
int main (int argc, char *argv[])
{
ifstream mousefile;
mousefile.open(argv[1]);
string mouse_dna;
getline(mousefile, mouse_dna);
ifstream humanfile;
humanfile.open(argv[2]);
string human_dna;
getline(humanfile, human_dna);
ifstream unknownfile;
unknownfile.open(argv[3]);
string unknown_dna;
getline(unknownfile, unknown_dna);
int len = mouse_dna.size();
int mouseDistance = 0, humanDistance = 0;
for(int i=0; i<len; i++)
{
if(mouse_dna[i] != unknown_dna[i])
{
mouseDistance++;
}
}
for(int i=0; i<len; i++)
{
if(human_dna[i] != unknown_dna[i])
{
humanDistance++;
}
}
double similarity_scoreH = (len - humanDistance) / len;
double similarity_scoreM = (len - mouseDistance) / len;
cout << "MouseCompare = " << similarity_scoreM << endl;
cout << "HumanCompare = " << similarity_scoreH << endl;
if (similarity_scoreH == similarity_scoreM)
cout << "identity cannot be determined" << endl;
else if (similarity_scoreH > similarity_scoreM)
cout << "human" << endl;
else if (similarity_scoreM > similarity_scoreH)
cout << "mouse" << endl;
return 0;
}
You use arg[1], arg[2], and arg[3]. You may want arg[0], arg[1], and arg[2].
I'm making a program that converts a string that the user enters such as "APPLE" into a binary number through the corresponding ASCII numbers that represent each character of the string "APPLE." For example A = 65 in ascii etc.. I've created a function that converts the string into a binary but it doesn't seem to be working. It displays "The equivalent binary number is: 0031F240for A" in an infinite loop and gives me "0031F240for" instead of being in the binary version of 65. I know this function works for converting a decimal number into binary because I've tried it, but I think my implementation of the bin[] array is messing things up. Any help would be appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <fstream>
using namespace std;
class RandomString
{
private:
string input;
string bin[100];
public:
RandomString() : bin(), input("")
{
}
void getData()
{
cout << "Enter the word to be encoded into a binary file.";
cin >> input;
}
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(num != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
bin[i].insert(0, "1");
num = num / 2;
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
void display()
{
}
};
I haven't test if the result is correct but this code convert a string to binary. Probably you have to modify it to fit with ASCII codes.
void DecimalToBinary(char a,std::vector<char>& v)
{
if(a==0)
v.push_back(0);
if(a==1)
v.push_back(1);
else
{
v.push_back(a%2);
DecimalToBinary(a/2,v);
}
}
int main()
{
std::vector<char> v;
std::string line;
getline(std::cin,line);
std::istringstream input(line);
char c;
while(input >> c)
{
DecimalToBinary(c,v);
}
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout,""));
}
First Your while loop never stops because you don't change the value of i inside the while loop, so int(input[i]) has always the same value, you have to use break somewhere or i++, but I don't know if the result is correct,I think recursion is better than while in this situation, but anyway try the following:
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(int(input[i]) != 0)
{
if (num % 2 == 0)
{
bin[i].insert(0, "0");
break;
}
else
{
bin[i].insert(0, "1");
num = num / 2;
}
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
Second, doing std::cout << bin you print a memory address, not the contents of the bin.
while(int(input[i]) != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
{
bin[i].insert(0, "1");
}
num = num / 2;// this line should be in both case.
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
I've changed num = num / 2 for both cases. Please check it.
You may want to change the 'bin' in
cout << "The equivalent binary number is: " << bin
to 'bin[i]'.
Because 'bin' is a string array, also the pointer/address to the string array, so 'cout << bin' will always output the address.