So, i need to insert space after space in char string, for example:
we have string: hello world, and function should be return hello world
hello world something else => hello world something else
hello world => hello world (4 spaces) (not necessarily, but preferably)
how?? (definitely need to be used char string)
my solution (it does not work correctly because it insert only 1 space)
from hello world something it returns hello world something:
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
char* addSpaces(char* str) {
char* p = strchr(str, ' ');
if (p) {
p++;
int n = strlen(p);
p[n + 1] = 0;
while (n) {
p[n] = p[n - 1];
n--;
}
*p = ' ';
}
return str;
}
int main(void) {
const int stringCount = 1;
const int c = 500;
char cstring[stringCount][c];
string str[stringCount];
for (int i = 0; i < stringCount; i++) {
cout << "Enter " << i + 1 << ". line: ";
cin.getline(cstring[i], c);
str[i] = cstring[i];
}
for (int i = 0; i < stringCount; i++) {
cout << "First function result with char in parameter: ";
char* result = addSpaces(cstring[i]);
cout << result << endl;
}
}
Using Dynamic Array:
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
char *add(char *arr, int lastIndex, char key)
{
int len = sizeof(&arr);
if (len == 0 || arr[len - 1] != '\0')
{
char newArr[len + 100];
newArr[len + 100 - 1] = '\0';
strncpy(newArr, arr, len);
*arr = *newArr;
}
arr[lastIndex] = key;
return arr;
}
int main(void)
{
std::string line;
const int stringCount = 1;
const int c = 500;
cout << "Enter line: ";
std::getline(std::cin, line);
int spaceCount = 0;
char cstring[0];
int lastUpdated = 0;
for (int i = 0; i < sizeof(line); i++)
{
add(cstring, lastUpdated++, line[i]);
if (line[i] == ' ')
{
add(cstring, lastUpdated++, ' ');
}
}
cout << cstring << endl;
}
OR
Check for space first and start char str with len+spaces. and add extra space on each iterate. Else error out of index bound can come.
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(void)
{
std::string line;
const int stringCount = 1;
const int c = 500;
cout << "Enter line: ";
std::getline(std::cin, line);
cout << line << endl;
int spaceCount = 0;
for (int i = 0; i < sizeof(line); i++)
{
if (line[i] == ' ')
{
spaceCount += 1;
}
}
char cstring[stringCount + spaceCount];
int j = 0;
for (int i = 0; i < sizeof(line); i++)
{
if (line[i] == ' ')
{
cstring[j++] = ' ';
cstring[j++] = ' ';
}
else
{
cstring[j++] = line[i];
}
}
cout << cstring << endl;
}
Modify the main() function according to your needs:
#include <iostream>
#include <cstring>
#include <cstdlib>
#define MAXLEN 500
void add_space(char* str, size_t index, size_t n) {
if (n >= MAXLEN) {
std::cerr << "Cannot further expand the array!" << std::endl;
abort();
}
for (auto i = n; i >= index; --i)
str[i] = str[i - 1];
str[index] = ' ';
}
char* double_spaces(char* str, size_t n) {
for (size_t i = 0; i < n; ++i)
if (str[i] == ' ')
add_space(str, i++, n++);
return str;
}
int main() {
char str[MAXLEN] = "hello world";
std::cout << double_spaces(str, std::strlen(str)) << std::endl;
return 0;
}
Sample Output:
For str[] = "hello world" function returns "hello world"
For str[] = "hello world something else" function returns "hello world something else"
For str[] = "hello world" function returns "hello world"
PS: Better algorithms are possible but they mostly require use of advanced data structures so sticking to the asker's demand of using simple cstrings I have provided one of the simplest and easy to understand solution.
Analysis: The insertion operation requires O(n-index) time which can be reduced by using something similar to ArrayLists.
I need some help with the use of parallel vectors. What I want to do is have 2 vectors, 1 containing the alphabet, and the other containing the alphabet the other way around. When someone types in a word, it prints out the word using the inverted alphabet.
This is what I've done up until now and I'm not too sure if I'm on the right track or not:
#include <iostream>
#include <ctype.h>
using namespace std;
void search(char alfab[], char cripto[], int code){
cout << "Introduce your message: " << endl;
cin >> code;
for(int i = 0; i < code; i++)
{
if(code == 0){
cout << "Your code is:" << cripto[i] << endl;
}
}
}
int main(){
char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
char code;
}
Think about how you would do this by hand. Then try to translate those steps to code.
Get user input
for each letter:
decide which letter of your reversed alphabet it is
write that new letter down in the same position as the original
output new string
Try something more like this instead:
#include <iostream>
#include <string>
static const char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
static const char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
std::string invert(const std::string &word){
std::string inverted = word;
for(std::string::size_type i = 0; i < inverted.size(); ++i)
{
char ch = inverted[i];
for(int j = 0; j < 26; ++j)
{
if (alfab[j] == ch)
{
inverted[i] = cripto[j];
break;
}
}
}
return inverted;
}
int main(){
std::string word;
std::cout << "Enter a word: " << std::endl;
std::cin >> word;
std::cout << "Your code is: " << invert(word) << std::endl;
}
You could try using one array:
std::string invert(const std::string& original)
{
static const char cripto[26] =
{
'z','y','x','w',
'v','u','t','s','r',
'q','p','o','n','m',
'l','k','j','i','h',
'g','f','e','d','c',
'b','a'
};
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += cripto[c - 'a'];
}
return inverted_text;
}
Edit 1: Using some math
You could simplify the encryption (inversion) by using some math.
std::string invert(const std::string& original)
{
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += (25 - (c - 'a')) + 'a';
}
return inverted_text;
}
Using transform
You could use std::transform:
char invert_char(char c)
{
return (25 - (c - 'a')) + 'a':
}
//...
std::transform(original_word.begin(), original_word.end(),
original_word.begin(), invert_char);
For example I enter decimal number 210 that is symbol "Ò".
For example code
int a = 210;
wcout << wchar_t (a);
works fine, but before "wcout" I use "cout" and they are not compatible.
int main() {
string a = "\u";
string b = "210";
string c = a + b;
cout << b + a << endl;
cout << "Second cout message...";
}
ERROR:
main.cpp:4:15: error: \u used with no
following hex digits
string a = "\u";
^~
1 error generated.
compiler exit status 1
You can use std::wcrtomb to convert wide character to multi byte string. See https://en.cppreference.com/w/cpp/string/multibyte/wcrtomb
#include <iostream>
#include <cwchar>
#include <clocale>
int main() {
std::setlocale(LC_ALL, "en_US.utf8");
wchar_t wc = 127820;
char mbstr[5]{};
std::mbstate_t state{};
std::wcrtomb(mbstr, wc, &state);
std::cout << mbstr << std::endl;
}
https://ideone.com/QVMppe
Also if you are interested in what Unicode is and how it is encoded with variable width character encoding, see https://en.wikipedia.org/wiki/UTF-8
UTF-8 is very easy to encode manually, eg:
std::string toUTF8(uint32_t cp)
{
char utf8[4];
int len = 0;
if (cp <= 0x007F)
{
utf8[0] = static_cast<char>(cp);
len = 1;
}
else
{
if (cp <= 0x07FF)
{
utf8[0] = 0xC0;
len = 2;
}
else if (cp <= 0xFFFF)
{
utf8[0] = 0xE0;
len = 3;
}
else if (cp <= 0x10FFFF)
{
utf8[0] = 0xF0;
len = 4;
}
else
throw std::invalid_argument("invalid codepoint");
for(int i = 1; i < len; ++i)
{
utf8[len-i] = static_cast<char>(0x80 | (cp & 0x3F));
cp >>= 6;
}
utf8[0] |= static_cast<char>(cp);
}
return std::string(utf8, len);
}
int main()
{
std::string utf8 = toUTF8(210);
std::cout << utf8;
}
Live Demo
Make sure your console actually supports displaying UTF-8 text.
The main problem I'm having is to read out values in binary in C++ (python had some really quick/easy functions to do this)
I just need the same. So at the moment I have:
ValWord< uint32_t> data1=//[SOME READ FUNCTION]
When I use cout << data1; It gives me a number e.g 2147581953
I want this to be in binary and eventually each "bit" needs to be in its own bin including all '0's e.g:
for (int i = 31; i >= 0; i--) {
cout << binary[i];
}
Would give me this 32 bit long binary number. When I've had it as a straight forwward int, I've used:
int data[32];
bitset<32>(N) = data1;
for(int i=31; i >=0; i--) {
data[i]=(bitset<32>(N[i]).to_ulong());
}
for (int i = 31; i >= 0; i--) {
cout << data[i];
}
But this just gives me error messages. Any ideas?
Maybe this:
#define CPlusPlus11 0
#if CPlusPlus11
int main()
{
std::uint32_t value(42);
std::bitset<32> bits(value);
std::cout << bits.to_string() << std::endl;
// Storing integral values in the string:
for(auto i: bits.to_string(char(0), char(1))) {
std::cout << (int)i;
}
std::cout << std::endl;
return 0;
}
#else
int main()
{
std::uint32_t value(42);
std::bitset<32> bits(value);
std::cout << bits.to_string() << std::endl;
char data[32];
for(unsigned i = 0; i < 32; ++i) {
data[i] = bits[i];
}
for(unsigned i = 32; i; --i) {
std::cout << int(data[i-1]);
}
std::cout << std::endl;
return 0;
}
#endif
Note: Your expressions bitset<32>(N) = data1 and bitset<32>(N[i]) are code smell.
In general, transforming a number into a string for a given base, is quite ubiquitous:
#include <cassert>
#include <string>
static char const Digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static size_t const DigitsSize = sizeof(Digits) - 1;
static size_t const BufferSize = 32;
std::string convert(unsigned number, unsigned base) {
assert(base >= 2 and base <= DigitsSize);
char buffer[BufferSize] = {};
char* p = buffer + BufferSize;
while (number != 0) {
*(--p) = Digits[number % base];
number /= base;
}
return std::string(p, (buffer + BufferSize) - p);
}
Note: BufferSize was computed for the minimum base of 2, base 1 and base 0 are non-sensical.
Note: if the number can be negative, the simplest is to test for it beforehand, and then use its opposite; a special caveat is that the opposite of the minimum value of a 32 bits integer cannot be represented by a 32 bits integer in base 2.
I have some simple functions i use for this, using stl, here is one for binary:
#include <iostream>
#include <algorithm>
using namespace std;
string binary( unsigned long n )
{
string result;
do result.push_back( '0' + (n & 1) );
while (n >>= 1);
reverse( result.begin(), result.end() );
return result;
}
int main()
{
cout << binary(1024) << endl;
cout << "Hello World" << endl;
return 0;
}
Hope this is of use to you!
Let me know if you need something more performant and I can try to rustle up some Assembler code for you.
I'm trying to convert an incoming sting of 1s and 0s from stdin into their respective binary values (where a string such as "11110111" would be converted to 0xF7). This seems pretty trivial but I don't want to reinvent the wheel so I'm wondering if there's anything in the C/C++ standard libs that can already perform such an operation?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char * ptr;
long parsed = strtol("11110111", & ptr, 2);
printf("%lX\n", parsed);
return EXIT_SUCCESS;
}
For larger numbers, there as a long long version, strtoll.
You can use std::bitset (if then length of your bits is known at compile time)
Though with some program you could break it up into chunks and combine.
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
}
You can use strtol
char string[] = "1101110100110100100000";
char * end;
long int value = strtol (string,&end,2);
You can use Boost Dynamic Bitset:
boost::dynamic_bitset<> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
string getBinaryString(int value, unsigned int length, bool reverse) {
string output = string(length, '0');
if (!reverse) {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << i)) != 0) {
output[i] = '1';
}
}
}
else {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << (length - i - 1))) != 0) {
output[i] = '1';
}
}
}
return output;
}
unsigned long getInteger(const string& input, size_t lsbindex, size_t msbindex) {
unsigned long val = 0;
unsigned int offset = 0;
if (lsbindex > msbindex) {
size_t length = lsbindex - msbindex;
for (size_t i = msbindex; i <= lsbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << (length - offset));
}
}
}
else { //lsbindex < msbindex
for (size_t i = lsbindex; i <= msbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << offset);
}
}
}
return val;
}
int main() {
int value = 23;
cout << value << ": " << getBinaryString(value, 5, false) << endl;
string str = "01011";
cout << str << ": " << getInteger(str, 1, 3) << endl;
}