For self-study, here there are my 2 version of strncat (one with pointer+offset notation and one array version):
// 08_38.cpp
#include <iostream>
#include <cstring>
char * strncatPtr(char * a, char * b, size_t n);
char * strncatArr(char * a, char * b, size_t n);
int main (void) {
char string1[20] = "foobarqwerty";
char string2[20] = "asd";
// strncat
std::cout << "-----------------------" << std::endl;
std::cout << "--------STRNCAT--------" << std::endl;
std::cout << "-----------------------" << std::endl;
std::cout << strncat(string2, string1, 6) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatPtr(string2, string1, 4) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatArr(string2, string1, 3) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
return 0;
}
// ------------------------------------
char * strncatPtr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; *(a+i) != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((*(a+i+j) = *(b+j)) != '\0') && (j < n-1);
j++);
return a;
}
char * strncatArr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; a[i] != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((a[i+j] = b[j]) != '\0') && (j < n-1);
j++);
return a;
}
I don't get why when i test them it considers size = 6 for every function call
-----------------------
--------STRNCAT--------
-----------------------
asdfoobar
asd
asdfoobar
asd
asdfoobar
asd
but if i test them separately, by commenting 2 different calls each time, they works fine... could you please enlighten me?
If the number of chars copied is less then the length of the string being concatenated then you are not adding a null-terminator to indicate the end of the string.
Related
I am running a C++ program to sort strings as numbers.
I am saving strings in a char array vector but want to sort numbers as numbers so I am converting number strings into long doubles by calling "tonum()" then converting them back to strings when I am done by calling "tostring()". I am calling "numstr()" strictly for readability and debugging. I convert numbers 0 through 7 and the 6th number across for each value changes every time I run it. In my actual program, the first 5 numbers also seem to change. How do I get consistent results for a long double so that I can properly sort long doubles in char arrays?
#include<iostream>
std::string::size_type sz;
//___________________________________________________
std::string tonum(std::string str)
{
const int len = sizeof(long double);
std::string out = "0000000000000000";
union
{
long double dbl;
char array[len];
};
try
{
dbl = stold(str);
}
catch(std::exception &err)
{
dbl = 0;
}
for (int i = 0; i < len; i++)
{
std::cout << (int)array[i] << "\n";
out[len-i-1] = array[i];
}
return(out);
}
//___________________________________________________
std::string fromnum(std::string str)
{
const int len = sizeof(long double);
std::string out = "";
union
{
long double dbl;
char array[len];
};
for (int i = 0; i < len; i++)
{
array[len-i-1] = str[i];
}
out = std::to_string(dbl);
return(out);
}
//_____________________________________________________
std::string numstr(std::string str)
{
std::string out = fromnum(str) + ":";
for (int i = 0; i < str.length(); i++)
{
std::string look = std::to_string(str[i]);
int lookint = stold(look,&sz);
if (lookint < 0) lookint += 256;
std::string look2 = std::to_string(lookint);
out += look2 + " ";
}
return(out);
}
//_____________________________________________________
int main()
{
std::cout << numstr(tonum("0")) << "\n";
std::cout << numstr(tonum("1")) << "\n";
std::cout << numstr(tonum("2")) << "\n";
std::cout << numstr(tonum("3")) << "\n";
std::cout << numstr(tonum("4")) << "\n";
std::cout << numstr(tonum("5")) << "\n";
std::cout << numstr(tonum("6")) << "\n";
std::cout << numstr(tonum("7")) << "\n";
}
//_____________________________________________________
I want to display a progress bar however putting the printing code inside a separate function seems to invoke an std::flush as each time the progress bar is printing in a new line. This did not happen when the code was used inline
The code:
#include <iostream>
#include <unistd.h>
void load(int curr, int total) {
std::cout << "\n[";
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << "=";
else if (i == pos) std::cout << ">";
else std::cout << " ";
}
std::cout << "]" << int(float(curr)/(float)total * 100.0) << " %\r";
std::cout.flush();
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i,5);
}
std::cout << std::endl;
return 0;
}
What it does:
[> ]0 %
[==========> ]20 %
[====================> ]40 %
[==============================> ]60 %
[========================================> ]80 %
[==================================================]100 %
What it's supposed to do: print all on the same line
The first line in your function outputs \n, which is what makes it print on a new line every iteration.
Fix:
#include <iostream>
void load(int curr, int total) {
std::cout << '[';
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << '=';
else if (i == pos) std::cout << '>';
else std::cout << ' ';
}
std::cout << ']' << int(float(curr)/(float)total * 100.0) << " %\r" << std::flush;
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i, 5);
}
std::cout << '\n';
}
I'm trying to measure the time taken for insertion sort (avg, best, and worst for certain a size, n times) and storing all results in a 2D array
Here is the code for it:
#include <iostream>
#include <sys/time.h>
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
std::cout << "insetion flag " << i << std::endl;
int key = array[i];
int j = i - 1;
while (key < array[j] && j >= 0) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
}
void getRandomArray(int* avg, int* best, int* worst, int size) {
srand((unsigned)time(0));
for (int i = 0; i < size; i++) {
//std::cout << "rand flag " << i << std::endl;
avg[i] = (rand() % 100) + 1;
}
for (int i = 0; i < size; i++) {
//std::cout << "copy flag " << i << std::endl;
best[i] = avg[i];
}
insertionSort(best, size);
for (int i = 0, j = size; i < size; i++, j--) {
//std::cout << "rev flag " << i << std::endl;
worst[j] = best[i];
}
}
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
int times = atoi(argv[2]);
int* avg = new int[size];
int* best = new int[size];
int* worst = new int[size];
double** resTable = new double*[times];
for (int i = 0; i < times; i++) {
std::cout << i << std::endl;
resTable[i] = new double[3];
}
std::cout << "flag 1" << std::endl;
for (int i = 0; i < times; i++) {
getRandomArray(avg, best, worst, size);
std::cout << "flag 2" << std::endl;
resTable[i][0] = getComplx(avg, size);
std::cout << " avg ("<<i<<") (0) " << resTable[i][0] << std::endl;
resTable[i][1] = getComplx(best, size);
std::cout << " best ("<<i<<") (0) " << resTable[i][1] << std::endl;
resTable[i][2] = getComplx(worst, size);
std::cout << " worst ("<<i<<") (0) " << resTable[i][2] << std::endl;
printf("|%9.0f |%9.0f |%9.0f |", resTable[i][0], resTable[i][1], resTable[i][2]);
std::cout << " : loop no : " << i << std::endl;
}
std::cout << "after loop" << std::endl;
delete []avg;
std::cout << "after avg" << std::endl;
delete []best;
std::cout << "after best" << std::endl;
delete []worst;
std::cout << "after worst" << std::endl;
for (int i = 0; i < times; i++) {
std::cout << "after " << i << std::endl;
delete[] resTable[i];
}
delete []resTable;
std::cout << "last flag" << std::endl;
return 0;
}
In the main function I have a dynamically created array and store all data in it but it gives a segmentation fault when it reaches in last row to store data.
So I tried to skip storing in last row and it worked but this time when deleting at the end it again gives me the error "munmap_chunk() : invalid pointer"
I have checked other questions related to this but couldn't find what I am doing wrong here.
I know we can do it better with vectors but I am just trying to get a better understanding of the inner workings of pointers and memory allocation.
You've got two instances of reading/writing outside of allocated memory bounds, and two instances of using an uninitialized pointer.
First, in insersionSort:
while (key < array[j] && j >= 0) {
You use j to index the array before checking if the value is positive. This results in reading before the start of the array. You want to check j first:
while ( j >= 0 && key < array[j]) {
Then you have this in getRandomArray:
for (int i = 0, j = size; i < size; i++, j--) {
You start j at size, then use it to index the array. This writes past the end of the array. You want to start one element earlier:
for (int i = 0, j = size - 1; i < size; i++, j--) {
Finally, there's getComplx:
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
The gettimeofday function expects a pointer to a struct timeval, but in both cases you pass it an uninitialized pointer. Rather than making start and end pointers, make them instances of struct timeval and pass their addresses:
double getComplx(int* arry, int size) {
struct timeval start, end;
std::cout << "comp flag " << std::endl;
gettimeofday(&start, NULL);
insertionSort(arry, size);
gettimeofday(&end, NULL);
// also change -> to .
double timeTaken = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
return timeTaken;
}
This is a part of a program that I am writing to compute the addition of two integers as strings. (Writing my own bigInt class).
There appears to be a problem when I am adding the two integers together. Because they are both in vectors of char type, I had to add a '0' to each element of the vector before concatenating it into a string.
However, the results are still not what I am expecting:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string const Number = "1000";
string const Number2 = "1000";
vector<char> reverse;
vector<char> reverse2;
//cout << (rostrNumber[1] - '0') << endl;
cout << "Original Number: " << Number << endl;
reverse.clear();
for (int i = Number.size() - 1; i >= 0; i--)
{
reverse.push_back(Number[i]);
}
cout << "Reversed: " << endl;
cout << reverse[0] << reverse[1] << reverse[2] << reverse[3] << endl;
cout << endl << endl;
reverse2.clear();
{
for (int i = Number2.size() - 1; i >= 0; i--)
{
reverse2.push_back(Number[i]);
}
}
cout << "Adding these two integers" << endl;
vector<char> const rcvN1 = reverse;
vector<char> const rcvN2 = reverse2;
vector<char> Results;
Results.clear();
//Local copies
vector<char> vN1 = rcvN1;
vector<char> vN2 = rcvN2;
int iSize1 = vN1.size();
int iSize2 = vN2.size();
int i, iSize = iSize2;
int iC = 0, iR;
for (i = 0; i<iSize; i++)
{
iR = vN1[i] + vN2[i] + iC;
if (iR > 9)
{
iR -= 10;
iC = 1;
}
else
iC = 0;
Results.push_back(iR);
cout << Results[0] << endl;
}
if (iC > 0)
Results.push_back(iC);
string ostr;
vector<char>::const_reverse_iterator rIter = Results.rbegin();
for (; rIter != Results.rend(); rIter++)
ostr += *rIter +'0';
cout << "Results: " << ostr << endl;
system("PAUSE");
return 0;
}
If I have this as pointer to memory as a pointer to shorts:
unsigned short* ms = reinterpret_cast<unsigned short*>(_memory);
and I know the size of ms (number of this shorts), I would like to see running through all these shorts and their binary representation.
How can I access the bits of each short in C++?
To see the binary representation of any variable of type T, you can do something like this:
template <typename T>
void print_raw(const T & x)
{
const unsigned char * const p = reinterpret_cast<const unsigned char *>(&x);
for (std::size_t i = 0; i != sizeof(T); ++i)
{
if (i != 0) std::putchar(' ');
std::printf("%02X", p[i]);
}
}
You can plug this into your list of shorts.
(You could even replace printf by two lookups of index p[i] / 16 and p[i] % 16 in a suitable alphabet:
static const char alphabet = "01234567890ABCDEF";
std::putchar(alphabet[p[i] / 16]);
std::putchar(alphabet[p[i] % 16]);
Or replace it by a genuine binary printer:
void print_byte(unsigned char b)
{
for (std::size_t i = CHAR_BIT; i != 0; --i)
{
std::putchar(b & (1u << (i-1)) ? '1' : '0');
}
}
You can chain that into the previous loop instead of the two printf calls.)
cout << "\t" << dec << x << "\t\t Decimal" << endl;
cout << "\t" << oct << x << "\t\t Octal" << endl;
cout << "\t" << hex << x << "\t\t Hex" << endl;
cout << "\t" << bitset<MAX_BITS>(x) << endl;
try through bitset
EDIT(added code)
#include <iostream>
#include <bitset>
using namespace std;
int main( int argc, char* argv[] )
{
unsigned short _memory[] = {0x1000,0x0010,0x0001};
unsigned short* ms = reinterpret_cast<unsigned short*>(_memory);
for(unsigned short* iter = ms; iter != ms + 3/*number_of_shorts*/; ++iter )
{
bitset<16> bits(*iter);
cout << bits << endl;
for(size_t i = 0; i<16; i++)
{
cout << "Bit[" << i << "]=" << bits[i] << endl;
}
cout << endl;
}
}
or
#include <iostream>
#include <algorithm>
#include <bitset>
#include <iterator>
int main( int argc, char* argv[] )
{
unsigned short _memory[] = {0x1000,0x0010,0x0001};
unsigned short* ms = reinterpret_cast<unsigned short*>(_memory);
unsigned int num_of_ushorts = 3;//
std::copy(ms, ms+num_of_ushorts, ostream_iterator<bitset<16>>(cout, " "));
}
for (size_t i=0; i<N_SHORTS_IN_BUFFER; i++)
// perform bitwise ops
where N_SHORTS_IN_BUFFER is the number of shorts in memory.
The number of bits in a short is CHAR_BIT * sizeof(short).
If you are working under the assumption that an unsigned short has 16 bits, then you can retrieve each of them with bitwise operations:
for( unsigned short* iter = ms; iter != ms + num_of_ushorts; ++iter )
{
int bitN = ( *iter ) & ( 1 << N ); // get the N bit
}
As _memory points to a list of shorts your ms pointer can be used as an array.
unsigned short* ms = reinterpret_cast<unsigned short*>(_memory);
for (int i = 0; i < NUM_SHORTS_IN_MEM; i++)
cout << i << "th element\t" << ms[i] << endl;