I am writing a code where I take user user text input, convert it to binary, store each binary character in an element in an array and then print A or T for 0 and G or C for 1 at random. But the ATGC seem to not follow this rule and they come at random for every digit; 0 and 1. So If the binary is 0010101 I need output as ATGACTG. Also when I store the binary in an int variable, the zero in front of it vanishes. Is there a way to keep it?
#include <iostream>
#include <cstdlib>
#include <bitset>
#include <string>
#include <ctime>
int main()
{
using namespace std;
int p, i=0, a[100000];
int s;
string myString;
int binary;
cout << "Type your text: ";
std::getline (std::cin,myString);
for (std::size_t k=0; k < myString.size(); ++k)
{
std::bitset<8> y(myString[k]);
std::string dna = y.to_string();
binary = atoi(dna.c_str());
cout << binary;
while (binary != 0)
{
a[i] = binary % 10;
binary = binary / 10;
i++;
}
}
std::cout << std::endl;
srand(time(0));
for (int j = (i-1); j>-1; j--)
{
if (a[j] == 0)
{
p = rand() %2;
if (p==0)
cout<< "A";
else
cout<< "T";
}
if (a[j] == 1)
{
s = rand() %2;
if (s == 0)
cout<< "G";
else
cout<< "C";
}
else
{
cout << "";
}
}
}
I don't know why exactly you wrote so much wrong code, but I've managed to extract (and change) the code that actually does the job.
#include <iostream>
#include <string>
#include <bitset>
#include <ctime>
int main()
{
int i = 0, a[8];
std::string myString;
std::cout << "Type your text: " << std::endl;
std::getline(std::cin, myString);
for(auto x : std::bitset<8>(myString).to_string())
a[i++] = x == '1';
std::cout << std::endl;
srand(time(0));
for(int j = 0; j < i; ++j)
if(a[j] == 0)
std::cout << (rand() % 2 ? "T" : "A");
else if(a[j] == 1)
std::cout << (rand() % 2 ? "C" : "G");
std::cout << std::endl;
}
And here's neater version of main:
int main()
{
std::vector<int> a; // using std::vector
std::bitset<8> bs;
std::cout << "Type your text: " << std::endl;
std::cin >> bs; // std::bitset can be read from stream via operator>>
for(auto x : bs.to_string())
a.push_back(x == '1');
std::cout << std::endl;
srand(time(0));
for(auto x : a)
if(x == 0)
std::cout << (rand() % 2 ? "T" : "A");
else if(x == 1)
std::cout << (rand() % 2 ? "C" : "G");
std::cout << std::endl;
}
Just ask if you want an explanation on some specific part.
I told you not to convert the string to an integer. You didn't listen. This is why leading 0 vanishes.
Your output seams to be completely random because you reverse the order of characters in the sequence when reading the information from a.
Here is how I'd solve your problem: run online
#include <iostream>
#include <string>
#include <bitset>
#include <ctime>
#include <cstdlib>
int main()
{
std::cout << "Type your text: " << std::endl;
std::string in_str;
std::getline(std::cin, in_str);
std::string binary_str;
for(int i = 0; i < in_str.size(); ++i)
{
char c = in_str.at(i);
binary_str.append(std::bitset<8>(c).to_string());
}
std::cout << binary_str << std::endl;
srand(time(0));
for(int i = 0; i < binary_str.size(); ++i)
{
char c = binary_str.at(i);
if(c == '0')
std::cout << (rand() % 2 ? "T" : "A");
else
std::cout << (rand() % 2 ? "C" : "G");
}
std::cout << std::endl;
}
If you have any questions, ask me in the comments.
Edit: the OP asked me to explain all mistakes in his program.
Where did all those zeros gone?
To answer this question I'll have to explain all things your program does line-by-line.
Here you convert a symbol to a bitset:
std::bitset<8> y(myString[k])
For example: if k is 'a', then the y would be 01100001.
Here you convert the bitset to a string:
std::string dna = y.to_string();
In our example the dna would be "01100001".
Here you convert the string to an integer:
binary = atoi(dna.c_str());
A very simplified version of what atoi does:
binary = 0;
for(int i = 0; i < dna.size(); ++i)
binary = binary * 10 + (dna.at(i) - '0')
In our example the binary would be 1100001.
Note: that's NOT where you loose zeros. At this point you are still able to extract them because you know that you need to extract 8 digits. So you can append leading zeros to up it's length to 8.
The next line is where you actually loose zeros the first time because cout doesn't know that you want to print 8 digits.
cout << binary;
In our example it would print 1100001.
And here you loose zeros again because you stop extracting digits as soon as binary == 0 even if you extracted less than 8 digits. Also note that you are actually reversing what the function atoi just did with the only difference that you don't get your leading zeros back and the reverse order of bits (see the next paragraph):
while (binary != 0)
{
a[i] = binary % 10;
binary = binary / 10;
i++;
}
Why the output is "random"?
Here you are iterating through myString in the standard order
for (std::size_t k=0; k < myString.size(); ++k)
e.g. if myString is "abc" than
in the first iteration myString[k] would be 'a'
in the second iteration myString[k] would be 'b'
in the third iteration myString[k] would be 'c':
But in this loop you extract digits in reverse order:
while (binary != 0)
{
a[i] = binary % 10;
binary = binary / 10;
i++;
}
eg if binary is 1100001
in the 1st iteration you extract 1 and binary becomes 110000
in the 2nd iteration you extract 0 and binary becomes 11000
in the 3rd iteration you extract 0 and binary becomes 1100
in the 4th iteration you extract 0 and binary becomes 110
in the 5th iteration you extract 0 and binary becomes 11
in the 6th iteration you extract 1 and binary becomes 1
in the 7th iteration you extract 1 and binary becomes 0
Now you end up with an array where bits inside a character code are reversed, but different characters are stored in the array in the normal order.
e.g. If the input string was "abc", then a would become:
1,0,0,0,0,1,1, 0,1,0,0,0,1,1, 1,1,0,0,0,1,1
reversed 'a' reversed 'b' reversed 'c'
If you iterate through a in normal order, the order of bits inside character codes would be reversed. If you iterate through a in reverse order, you get the reversed order of characters.
As a rule of thumb: don't program by guessing, program by thinking.
Further reading
The Zen of Python. Most of this aphorisms are applicable to every programming language with the exception of Brainfuck
Raw C arrays are evil
Related
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
int main()
{
int masivs[24], x = 0, y = 0;
int negativi[20];
int pozitivi[20];
ifstream f;
f.open("f.txt");
while (f.good() && x < 24)
f >> masivs[x++];
f.close();
cout << masivs[1];
ofstream f2("f2.txt");
ofstream f1("f1.txt");
for (x = 0; x < 24; x++)
if (masivs[x] >= 0)
pozitivi[x] = masivs[x];
else
negativi[x] = masivs[x];
for (int k = 0; k < 8; k++)
{
f2 << negativi << endl;
}
for (int k = 0; k < 15; k++)
{
f1 << pozitivi << endl;
}
}
Ive been trying to find out how to do this for 2 days and im going crazy. Just please tell me how to do it. Im trying to divide the f.txt file numbers into f1.txt with the positives and f2.txt with the negatives. I have to read the f file with an array adn then write the positives in f1 and negatives in f2. and all the zeros in f3. Pls help ive been trying to find info on this but i cant do it.
the f.txt numbers:
-9
-8
-7
-6
-5
-4
-3
-2
-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
You have two major problems. One benign and one which leads to undefined behavior.
The benign problem is the statement
f2<<negativi<<endl;
This is exactly the same as
f2 << &negativi[0] << endl;
In other words, it writes a pointer to the first element of negativi.
The more serious problem is a buffer overflow in the loop
for (x = 0; x < 24; x++)
if (masivs[x] >= 0)
pozitivi[x] = masivs[x];
else
negativi[x] = masivs[x];
Here you use the same index x for both pozitivi, negativi and masivs. This index is only valid for masivs.
The loop as it works now with a single index x will not only put holes in the pozitivi and negativi arrays, but also go out of bounds of both.
The solution is to add another index, one each for the pozitivi and negativi arrays:
unsigned p = 0; // Index for positive number array
unsigned n = 0; // Index for negative number array
for (unsigned x = 0; x < 24; x++)
{
if (masivs[x] >= 0)
pozitivi[p++] = masivs[x];
else
negativi[n++] = masivs[x];
}
Afterwards you can use p and n as sizes for the corresponding array, to use when you write the result to the files.
And as mentioned in a comment to the question, the arrays aren't really needed which makes much of the code moot, and the whole program much simpler. And simplicity is better, as there's less chance of errors.
You can do a simple while(getline()) loop...
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <fstream>
int main()
{
int lineNumber, it = 0;
std::string line;
std::ifstream f("f.txt");
std::ofstream f1, f2;
f1.open("f1.txt");
f2.open("f2.txt");
while(std::getline(f, line)) //reads each line of f.txt ino a string
{
try
{
lineNumber = std::stoi(line);
}
catch(std::invalid_argument& e) //if value is not a number
{
std::cout << "VALUE IS NOT A NUMBER ON ITERATION " << it << '\n';
//std::abort();
continue;
}
catch(std::out_of_range& e) //if value is above +-2^32 +-1
{
std::cout << "VALUE OUT OF RANGE ON ITERATION " << it << '\n';
//std::abort();
continue;
}
if(lineNumber > 0)
{
f1 << lineNumber << '\n';
}
else
{
f2 << lineNumber << '\n';
}
it++;
}
f1.close();
f2.close();
}
This will get your desired output, file f1.txt containing all the positive numbers, and file f2.txt containing all the negative numbers.
I am trying to make a program that turns a string into encryption by going ten letters ahead of each letter. https://gyazo.com/86f9d708c2f02cf2d70dbc1cd9fa9a06 I am doing part 2. When I input "helloworld" something like 0x45 something comes up. Please help! This is due soon!
I am tried messing around with the for loops but it didn't help.
#include <iostream>
using namespace std;
int main()
{
//Input Message
cout << "Enter a message" << endl;
string message;
getline(cin, message);
//Convert Message to Numbers
int numMess[message.length()];
for (int i = 0; i<message.length(); i++) {
numMess[i] = (int)message[i];
}
cout << numMess << endl;
//Encrypt Number Message by adding ten to each one
int encryptNumMess[message.length()];
for (int a = 0; a < message.length(); a++){
encryptNumMess[a] = numMess[a] + 10;
if (encryptNumMess[a] > 122) {
encryptNumMess[a] = 97;
}
}
cout << encryptNumMess << endl;
//Convert Encrypted Number Message to letters
string encryption[message.length()];
for (int b = 0; b<message.length(); b++) {
encryption[b] = (char)encryptNumMess[b];
}
cout << encryption << endl;
return 0;
}
I expect when I type "helloworld" the final product will be "rovvygybvn"
If you are willing to scrap the hand-coded loops, you can use the STL algorithms such as std::transform to accomplish this:
But first, there are a few things you should do:
Don't use magic numbers such as 122, 97, etc. Instead use the actual character constants, i.e a, b, etc. However if we assume ASCII, where the alphabetic character codes are contiguous, your particular program could simply use a constant string to denote the alphabet, and then use simple indexing to pick out the character.
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
Then to get the letter a, a simple subtraction is all that's required to get the index:
char ch = 'b';
int index = ch - 'a'; // same as 'b' - 'a' == 98 - 97 == 1
std::cout << alphabet[index]; // will print 'b'
Given this, the next thing is to figure out what character is reached if you add 10 to the value, and if greater than 26, wrap around to the beginning of the alphabet. This can be done using modulus (remainder after division)
char ch = 'x';
int index = (ch - 'a' + 10) % 26; // Same as ('x' - 'a' + 10) % 26 == (120 - 97 + 10) % 26 == 33 % 26 == 7
std::cout << alphabet[index]; // will print 'h'
The next thing is to figure out the opposite, where given an encrypted character, you have to find the unencrypted character by subtracting 10. Here this wraps the opposite way, so a little more work needs to be done (not shown, but code sample reflects what is done).
Putting this all together, and using std::transform and lambdas, we get the following small program:
#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
#include <cmath>
int main()
{
//Input Message
const char *alphabet="abcdefghijklmnopqrstuvwxyz";
std::string message = "helloworld";
std::string result;
// set the encrypted string using the formula above and std::transform
std::transform(message.begin(), message.end(), std::back_inserter(result),
[&](char ch) { return alphabet[(ch - 'a' + 10) % 26]; });
std::cout << "Encrypted: " << result << '\n';
// convert back to unencrypted using the above formula and std::transform
std::string result2;
std::transform(result.begin(), result.end(), std::back_inserter(result2),
[&](char ch)
{ int index = ch - 'a' - 10; index = index < 0?26 - (abs(index) % 26):index % 26; return alphabet[index];});
std::cout << "Unencrypted: " << result2;
}
Output:
Encrypted: rovvygybvn
Unencrypted: helloworld
This code works for encrypt, if you want to decrypt you should chande newAlphabet and oldAlphabet
I comment in the code that which newAlphabet and oldAlphabet are for encrypt and which are for decrypt
#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
int main()
{
// For Encrypt
string newAlphabet = "abcdefghijklmnopqrstuvwxyz";
string oldAlphabet = "klmnopqrstuvwxyzabcdefghij";
// For Decrypt
//string newAlphabet = "klmnopqrstuvwxyzabcdefghij";
//string oldAlphabet = "abcdefghijklmnopqrstuvwxyz";
string input = "";
string output = "";
getline(cin, input);
int inputLen = input.size();
if (oldAlphabet.size() != newAlphabet.size())
return false;
for (int i = 0; i < inputLen; ++i)
{
int oldCharIndex = oldAlphabet.find(tolower(input[i]));
if (oldCharIndex >= 0)
output += isupper(input[i]) ? toupper(newAlphabet[oldCharIndex]) : newAlphabet[oldCharIndex];
else
output += input[i];
}
cout << output << endl;
return 0;
}
As others have already mentioned int numMess[message.length()]; is not valid c++.
If it works for you, you're using compiler extension which you really shouldn't rely on. The correct way would be:
std::vector <int> numMess(message.length());
Look up the std::vector reference for more info.
Next, int encryptNumMess[100]; creates a C array style array. encryptNumMess is the base pointer to the array. when you try std::cout << encryptNumMess it'll output the pointer value, NOT the array. You'll need a for loop for doing that, like so :
for(int i = 0; i < 100; ++i)
std::cout << encryptNumMess[i] << " ";
std::cout << endl;
The above also works when you convert this to a vector like we did with numMess whereas in that case, std::cout << encryptNumMess wouldn't even compile.
Thirdly, string encryption[100] creates an array of 100 strings! Not a string of size 100. To do that:
std::string foo(message.length(), '\0');
We have to specify what character to fill the string with. Thus us '\0'.
And now, for the string, to output it, you may use std::cout << foo.
Lastly, since arithmetic is allowed on char, the entire program may be shortened to just this
#include <iostream>
int main()
{
// Input Message
std::cout << "Enter a message" << std::endl;
std::string message, encryption;
getline(std::cin, message);
// Resize encryption string to the desired length
encryption.resize(message.length());
// Do the encryption
for(size_t i = 0; i < message.length(); ++i) {
encryption[i] = message[i] + 10;
if (encryption[i] > 122) {
encryption[i] = 97;
}
}
// Output the string
std::cout << encryption << std::endl;
return 0;
}
Of course, your encryption algorithm is still not correct as per instructions, but I'll leave that for you to figure out. I believe #PaulMcKenzie has already told you most of how to fix it, and also to not use magic numbers.
Hello i want to convert two characters at a time in a string to binary? how can i do that by applying simple arithmetic (that is by making my own function?)
For example: our string is = hello world:
Desired output (two characters at a time):
he // need binaryform of 0's and 1's (16 bits for 2 characters 'h' and 'e'
ll // similarly
o(space) // single space also counts as a character with 8 zero bit in binary.
wo
rl
d(space) // space equals a character again with 8 zero bits
how to go about with it. i dont want any ascii in between. directly from character to binary...is that possible?
If you're looking for a way to textually represent the binary representation of characters, then here's a small example of how you can do it:
A small function that prints out the binary representation of c to std::cout (will only work for standard ASCII letters):
void printBinary(char c) {
for (int i = 7; i >= 0; --i) {
std::cout << ((c & (1 << i))? '1' : '0');
}
}
Use it like this (will only print out pairs of characters):
std::string s = "hello "; // Some string.
for (int i = 0; i < s.size(); i += 2) {
printBinary(s[i]);
std::cout << " - ";
printBinary(s[i + 1]);
std::cout << " - ";
}
Outputs:
01101000 - 01100101 - 01101100 - 01101100 - 01101111 - 00100000 -
Edit:
Actually, using std::bitset this is all that is needed:
std::string s = "hello "; // Some string.
for (int i = 0; i < s.size(); i += 2) {
std::cout << std::bitset<8>(s[i]) << " ";
std::cout << std::bitset<8>(s[i + 1]) << " ";
}
Outputs:
01101000 01100101 01101100 01101100 01101111 00100000
If you want to store the binary numbers of the character pairs in a std::vector, as mentioned in a comment, then this will do it:
std::vector<std::string> bitvec;
std::string bits;
for (int i = 0; i < s.size(); i += 2) {
bits = std::bitset<8>(s[i]).to_string() + std::bitset<8>(s[i + 1]).to_string();
bitvec.push_back(bits);
}
This can be accomplished quickly and easily using the bitset class in the C++ STL.
Below is a function that you can use:
#include <string>
#include <bitset>
string two_char_to_binary(string s) // s is a string of 2 characters of the input string
{
bitset<8> a (s[0]); // bitset constructors only take integers or string that consists of 1s and 0s e.g. "00110011"
bitset<8> b (s[1]); // The number 8 represents the bit depth
bitset<16> ans (a.to_string() + b.to_string()); // We take advantage of the bitset constructor that takes a string of 1s and 0s and the concatenation operator of the C++ string class
return ans.to_string();
}
Sample Usage:
using namespace std;
int main(int argc, char** argv)
{
string s = "hello world";
if(s.length() % 2 != 0) // Ensure string is even in length
s += " ";
for(int i=0; i<s.length(); i += 2)
{
cout << two_char_to_binary(s.substr(i, 2)) << endl;
}
return 0;
}
I guess the thing you're looking for is casting. Try like this:
char *string = "hello world ";
short *tab = (short*)string;
for(int i = 0; i < 6; i++)
std::cout << tab[i] << std::endl;
I have to convert decimal numbers like 43.62 to binary. So i first wrote a basic program that converts 43 into binary. But I notice that my program prints out the binary number in reverse, so it prints 1 1 0 1 0 1 instead of 1 0 1 0 1 1. how can I fix this.
My Code:
#include <iostream>
using namespace std;
int main()
{
int number;
int remainder;
cout << "Enter a integer: ";
cin >> number;
while(number != 0)
{
remainder = number % 2;
cout << remainder << " ";
number /= 2;
}
int pause;
cin >> pause;
return 0;
}
Instead of sending each digit to cout, send them to an array. Then read the array out in reverse order. Or push them onto a stack, and then pop them back off the stack. Or...
Something of a sledgehammer to crack a nut, but here's a solution based on a recursive approach:
#include <iostream>
using namespace std;
void OutputDigit(int number)
{
if (number>0)
{
OutputDigit(number /= 2);
cout << number % 2 << " ";
}
}
int main()
{
OutputDigit(43);
return 0;
}
You can get the same output as you had before by simply moving the cout one line up!
Look at vector and think about how it could be useful to save the remainders instead of printing them right away.
Notice that you don't have to put things at the end of the vector. vector::insert lets you specify a position... could that be helpful?
Alternatively, the algorithm you created starts at the least significant digit. Is there a way to start from the most significant digit instead? If I have the number 42 (0101010), the most significant digit represents the 32s, and the 0 ahead of it represents the 64s. What happens if I subtract 32 from 42?
It would be easier to store the results and then print them backwards. Using recursion is also another possibility to do just that.
Most significant bit first:
const unsigned int BITS_PER_INT = CHAR_BIT * sizeof(int);
char bit_char = '0';
for (int i = BITS_PER_INT - 1;
i > 0;
--i)
{
bit_char = (value & (1 << i)) ? '1' : '0';
cout << bit_char << ' ';
}
cout << '\n';
cout.flush();
To print least significant bit first, change the direction of the for loop.
In C++, you can also use a bitset container to do this,
#include <bitset>
int i = 43;
std::bitset<sizeof(int)*CHAR_BIT> bin(i);
Just use string functions
string s ;
while(number != 0)
{
remainder = number % 2;
string c = remainder ? "1": "0";
s.insert(s.begin(),c.begin(),c.end());
number /= 2;
}
When you do such conversion by holding on to the remainder, the result will always be reverted. As suggested use bitwise &:
unsigned char bit = 0x80; // start from most significant bit
int number = 43;
while(bit)
{
if( bit & number ) // check if bit is on or off in your number
{
cout << "1";
}
else
{
cout << "0";
}
bit = bit >>1; // move to next bit
}
This example will start going through all your 8 bits of the number and check if the bit is on or off and print that accordingly.
Best option - Use C++ stringstream for formatting I/O
// Add the following headers
#include <sstream>
#include <algorithm>
// your function
stringstream ss;
// Use ss in your code instead of cout
string myString = ss.str();
std::reverse(myString.begin(),myString.end());
cout << myString;
So I'm trying to make a brute force string generator to match and compare strings in CUDA. Before I start trying to mess around with a language I don't know I wanted to get one working in C++. I currently have this code.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int sLength = 0;
int count = 0;
int charReset = 0;
int stop = 0;
int maxValue = 0;
string inString = "";
static const char charSet[] = //define character set to draw from
"0123456789"
"!##$%^&*"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int stringLength = sizeof(charSet) - 1;
char genChars()
{
return charSet[count]; //Get character and send to genChars()
}
int main()
{
cout << "Length of string to match?" << endl;
cin >> sLength;
cout << "What string do you want to match?" << endl;
cin >> inString;
string sMatch(sLength, ' ');
while(true)
{
for (int y = 0; y < sLength; y++)
{
sMatch[y] = genChars(); //get the characters
cout << sMatch[y];
if (count == 74)
{
charReset + 1;
count = 0;
}
if (count == 2147000000)
{
count == 0;
maxValue++;
}
}
count++;
if (sMatch == inString) //check for string match
{
cout << endl;
cout << "It took " << count + (charReset * 74) + (maxValue*2147000000) << " randomly generated characters to match the strings." << endl;
cin >> stop;
}
cout << endl;
}
}
Now this code runs and compiles but it doesn't exactly do what I want it to. It will do 4 of the same character, EX. aaaa or 1111 and then go onto the next without incrementing like aaab or 1112. I've tried messing around with things like this
for (int x = 0; x < sLength; x++)
{
return charSet[count-sLength+x];
}
Which in my mind should work but to no avail.
You basically just need to increment a counter, than convert the count number to base (size of char array)
Here's an example which does normal numbers up to base 16.
http://www.daniweb.com/code/snippet217243.html
You should be able to replace
char NUMS[] = "0123456789ABCDEF";
with your set of characters and figure it out from there. This might not generate a large enough string using a uint, but you should be able to break it up into chunks from there.
Imagine your character array was "BAR", so you would want to convert to a base 3 number using your own symbols instead of 0 1 and 2.
What this does is perform a modulus to determine the character, then divide by the base until the number becomes zero. What you would do instead is repeat 'B' until your string length was reached instead of stopping when you hit zero.
Eg: A four character string generated from the number 13:
14%3 = 2, so it would push charSet[2] to the beginning of the empty string, "R";
Then it would divide by 3, which using integer math would = 4. 4%3 is again 1, so "A".
It would divide by 3 again, (1) 1%3 is 1, so "A".
It would divide by 3 again, (0) -- The example would stop here, but since we're generating a string we continue pushing 0 "B" until we reach 4 our 4 characters.
Final output: BAAR
For an approach which could generate much larger strings, you could use an array of ints the size of your string, (call it positions), initialize all the ints to zero and do something like this on each iteration:
i = 0;
positions[i]++;
while (positions[i] == base)
{
positions[i] = 0;
positions[++i]++;
}
Then you would go through the whole array, and build the string up using charSet[positions[i]] to determine what each character is.