Int to Char array(part sums) - c++

I have problem with "tab" output. My program is going to show part sums.
I want to save those part sums in tab array but it shows only first sum.
here is code I wrote:
const char numbers[] = { "1 2 3 4" };
cout << numbers << endl;
for (int i = 0; i < strlen(numbers); ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < strlen(numbers); ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
How I can make it to show proper part sums like: 1 3 6 10

sizeof shows the size of the array in bytes, not the number of elements in the array.
Something like this will give you the number of elements:
int num_element = sizeof(numbers)/sizeof(numbers[0]);
Or a full solution:
const char numbers[] = { "1 2 3 4" };
int num_elements = sizeof(numbers)/sizeof(numbers[0]);
cout << numbers << endl;
for (int i = 0; i < num_elements; ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < num_elements; ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
Although the above should work after replacing num_element into your for loops, I suggest you looking into a std::array or std::vector

Your code has several problems. The first one is that function atoi will return an error because is will consider all string starting from &numbers[i] till the terminating zero. The other problem is that this in expression
_itoa_s(sum,&tab[i],sizeof(tab),10);
using tab[i] is incorrect.
Try the following code.
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
//...
const char numbers[] = { "1 2 3 4" };
char tab[20];
char *p = tab;
int sum = 0;
for ( size_t i = 0, n = std::strlen( numbers ); i < n; i++ )
{
if ( std::isdigit( numbers[i] ) )
{
sum += numbers[i] - '0';
p += std::sprintf( p, "%d ", sum );
}
}
std::cout << tab << std::endl;
At least I got output
1 3 6 10
Also it would be better to use std::istringstream instead of the for loop where you are extracting digits.

You are not retrieving the size of your arrays here.
Use SIZEOF_ARRAY to get the size of numbers in C.
But you tagged C++, so consider using std::array<> instead of a C-style array (it will expose the size of the array for you)

Firstly, cout << tab; prints only the first element.
Secondly, instead of writing the result to tab[i], create int cnt = 0; _itoa_s(sum,&tab[cnt],sizeof(tab),10); cnt++ By that way, you won't have empty characters in you tab array.
Thirdly, you can keep int tab[20], rather than to keep in char tab[].
Forthly, int num_elem = sizeof(numbers)/sizeof(numbers[0]);(as said above).

Related

what is the issue with this char reverse function?

so I wrote this code to reverse one of the names based on the user option the idea is to use another function to reverse and to use pointers but after trying all I could think of my code return the same name not changed the best I could do was changing the first letter of the name to a weird sign.
#include <iostream>
using namespace std;
void reverse(char* A) {
int count = 0;
char temp[10];
for (int i = 0; A[i] != NULL; i++)
count++;
for (int i = 0; A[i] != NULL; i++) {
temp[count]=A[i];
count--;
}
for (int i = 0; A[i] != NULL; i++) {
A[i] = temp[i];
}
}
int main(){
int x= 0;
int index;
char Name_list[5][10];
cout << "please enter the names of the student " << endl;
for (int i = 0; i < 5; i++) {
cin >> Name_list[i];
for (int j = 0; Name_list[i][j] != NULL; j++) {
x++;
}
while (x > 10)
{
x = 0;
cout << "you have entered more then the allowed number of characters per name enter another name " << endl;
cin >> Name_list[i];
for (int j = 0; Name_list[i][j] != NULL; j++) {
x++;
}
}
x = 0;
}
for (int i = 0; i < 5; i++) {
cout << Name_list[i] << endl;
}
cout << "please enter the index of the name you want to reverse" << endl;
cin >> index;
while (index>4||index <0)
{
cout << "you entered incorrect index please enter a number from 0 to 4 " << endl;
}
reverse(Name_list[index]);
for (int i = 0; i < 5; i++) {
cout << Name_list[i] << endl;
}
system("pause");
}
For starters such a function should return a pointer to the result string. That is it should be declared like
char * reverse( char *s );
Note: do not use variable names consisting from upper case letters.
The type int can be not large enough to store length of a string. Instead use the type size_t.
char * reverse( char *s )
{
size_t count = 0;
//...
It is totally unclear why there is present an array with the number of elements equal to the magic number 10
char temp[10];
To reverse a string there is no need to declare an auxiliary array. Such an approach is principally wrong.
In this for loop
for (int i = 0; A[i] != NULL; i++)
there is compared an object of the type char with the pointer NULL. The compiler should issue a message for such a wrong comparison. It seems you mean
for (int i = 0; A[i] != '\0'; i++)
In any case the introduced variable i in this first for loop is redundant because you already has the variable count.
As you have the array temp with the fixed size equal to 10 then the both loops after the first loop can invoke undefined behavior even if the length of the source string is equal exactly to 10.
And the result string is not zero terminated.
The function can look the following way.
char * reverse( char *s )
{
size_t count = 0;
while ( s[count] ) ++count;
for ( size_t i = 0; i < count / 2; i++ )
{
char c = s[i];
s[i] = s[count - i - 1];
s[count - i - 1] = c;
}
return s;
}
Or using standard functions you could write the function reverse the following way
#include <utility>
#include <cstring>
//...
char * reverse( char *s )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n-i-1] );
}
return s;
}
Pay attention to that there is the standard algorithm std::reverse. Using it you could reverse a string the following way
std::reverse( s, s + std::strlen( s ) );
for (int i = 0; A[i] != NULL; i++) {
temp[count]=A[i];
count--;
}
If i goes up from 0 to 5, count goes down from 6 to 1.
Ok, a few things.
If you want do some string manipulation, look into the stdlib. Unless you are doing this for class.
Your writing everything to the end of the temp. buffer
You need to add an extra character at the end of the strings for the null byte (I think this implementation may allow for a seg. fault)

c++ reverse Array elements using dynamic Allocation Operators

Hi i'm the beginner of c++.
This time, I try to reverse Array 's element-order using dynamic Allocation Operator.
For example an array{1,2,3,4} will be rearranged {4,3,2,1} through calling function 'reverseArray'.
Everything works fine but somehow i got unwanted integer '-1' along with rearranged Array.
For example {-1,4,3,2,1}.
It means i did wrong and i really want to learn my fault.
Here is my code, please help me to figure out.
#include<iostream>
#include<new>
using namespace std;
void reverseArray(int [] , int);
int main(){
int num=0;
cout << "enter size of pointer : " ;
cin >> num ;
int *pointerArray = new int [num];
cout << "enter integer numbers in pointer" << endl;
for(int index = 0 ; index < num ; index++){
cin >> pointerArray[index];
}
reverseArray(pointerArray, num);
delete[] pointerArray;
return 0 ;
}
void reverseArray(int reverse[], int Size){
int*ptArray[Size];
cout << "the reverse order of entered numbers is : " << endl;
for(int index = 0 ; Size >= 0 ; index++) {
ptArray[index] = &reverse[Size];
cout << *ptArray[index] << " " ;
--Size;
}
return ;
}
This function
void reverseArray(int reverse[], int Size){
int*ptArray[Size];
cout << "the reverse order of entered numbers is : " << endl;
for(int index = 0 ; Size >= 0 ; index++) {
ptArray[index] = &reverse[Size];
cout << *ptArray[index] << " " ;
--Size;
}
return ;
}
does not make sense.
For starters variable length arrays
int*ptArray[Size];
is not a standard C++ feature.
Secondly in this loop
for(int index = 0 ; Size >= 0 ; index++) {
ptArray[index] = &reverse[Size];
cout << *ptArray[index] << " " ;
--Size;
}
there is access beyond the arrays.
For example let's assume that Size is equal to 1.
In this case within the ,loop we have
ptArray[0] = &reverse[1];
and then
ptArray[1] = &reverse[0];
However the only valid index for such arrays is 0.
It is unclear what you are trying to do.
If you want to reverse an array in place then the function can look like
void reverseArray( int a[], size_t Size )
{
for ( size_t i = 0; i < Size / 2; i++ )
{
// you can use the standard function std::swap here
int tmp = a[i];
a[i] = a[Size - i - 1];
a[Size - i - 1] = tmp;
}
}
And in main after calling the function you can output the reversed array .
Pay attention to that there is standard algorithm std::reverse that can do the rask.
You could just write
std::reverse( reverse, reverse + num );
Here is a demonstrative program.
#include <iostream>
#include <algorithm>
void reverseArray( int a[], size_t Size )
{
for ( size_t i = 0; i < Size / 2; i++ )
{
// you can use the standard function std::swap here
int tmp = a[i];
a[i] = a[Size - i - 1];
a[Size - i - 1] = tmp;
}
}
int main()
{
const size_t N = 5;
int *a = new int[5] { 1, 2, 3, 4, 5 };
for ( size_t i = 0; i < N; i++ ) std::cout << a[i] << ' ';
std::cout << '\n';
reverseArray( a, N );
for ( size_t i = 0; i < N; i++ ) std::cout << a[i] << ' ';
std::cout << '\n';
std::reverse( a, a + N );
for ( size_t i = 0; i < N; i++ ) std::cout << a[i] << ' ';
std::cout << '\n';
delete [] a;
return 0;
}
Its output is
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
In your code you access the array out-of-bounds on the very first iteration, because for an array of size Size valid indices are 0 up to Size-1
It is not clear why you create an array of pointers, and int*ptArray[Size]; is a variable lenght array (VLA) which is not standard C++. Further, you do not need to include <new>.
To print a dynamically sized (ie size is taken from input) array you would use a std::vector and a loop:
#include <vector>
#include <iostream>
int main(){
size_t size;
std::cout << "enter size: ";
std::cin >> size;
std::vector<int> data(size);
for (auto& element : data) std::cin >> element;
for (size_t i = 0; i < data.size(); ++i) {
std::cout << data[ data.size()-1-i ]; // first element printed is data[data.size()-1]
}
}
If you want to reverse the array, not just print it in reverse order, there is std::reverse in <algorithm>. The algorithm also works with dynamically allocated arrays:
#include <iostream>
#include <algorithm>
int main(){
size_t size;
std::cout << "enter size: ";
std::cin >> size;
int* data = new int[size];
for (size_t i=0; i<size; ++i) std::cin >> data[i];
std::reverse(data,data+size);
for (size_t i=0; i<size; ++i) std::cout << data[i];
delete [] data;
}
#include
using namespace std;
int main() {
int n;
cin>>n;
int temp=n;
int rem=0;
int i=0;
while (n>0) {
n= n/10;
i++;
}
int *arr = new int(i);
i=0;
while (temp>0) {
rem=temp%10;
arr[i]=rem;
i++;
temp= temp/10;
}
int t=0;
while(t<i) {
cout<<arr[t]<<" ";
t++;
}
return 0;
}

Create randomly sized (within a certain range) arrays over many iterations

I am trying to create many arrays consisting of random numbers and of random size between the range of, say, 1 and 20 elements. My code works SOMETIMES.
I am using a random number between my desired range to determine the array size. If the first iteration produces an array size of value 10, say, then for some reason my code does not want to create any arrays of size larger than 10. Various arrays will be created (and the list of those arrays will be outputed) until a certain iteration produces a random number larger than 10. Then I get this error:
Array index out of range numbers->[11] valid upto numbers[9]
"numbers" is the name of the array. Here is the relevant portion of my code:
srand(time(0));
int j, flag = 0;
int temp;
int rand=1;
for(int t=0; t<50; t++)
{
int length = rand()% 20 + 1;
cout<<"length is " << length << endl;
int numbers[length];
for(int i = 0; i < length; i++)
{
numbers[i]=rand();
cout << numbers[i] << endl;
}
for(j=0; (j<=length); j++)
{
for (int i=0; i<(length-1); i++)
{
if(numbers[i+1]<numbers[i])
{
temp=numbers[i];
numbers[i]=numbers[i+1];
numbers[i+1]=temp;
flag++;
}
}
}
cout << "Number of Swaps : " << flag << endl;
}
As #Bob__ wrote, allocating variable length arrays is not C++ standard. It might work sometimes on specific compilers, but it may break on others.
But there are good alternatives. You can allocate dynamic memory with new. For instance:
int *array = new int[size];
array[0] = 3;
array[1] = 5;
cout << array[1];
delete [] array;
Don't forget to delete the memory with delete afterwards.
Or you could use vector<int>. It's a STL-container, that was made for exactly this purpose.
#include <vector>
using namespace std;
...
vector<int> vec(size);
vec[0] = 3;
vec[1] = 5;
cout << vec[1];
Variable Length Arrays are not in C++ standard, but only offered as extension by some compilers. I wouldn't trust them and you don't really need anything like that in your code.
You can declare your array outside the outer for loop as you know its max lenght:
#define MAXL 20
int numbers[MAXL];
for ...
int length = rand() % MAXL + 1;
...
Besides, if you are implementing a bubble sort I think that the condition of the inner i loop should be i < length - j
rand is used in two contexts. As a variable int rand and as a function std::rand(). I'd suggest to delete any using namespace std; but since the variable is not needed anyways you could as well delete int rand = 1;. Note that rand() is a C function. You may use it but IMHO std::rand() is more pure C++.
int numbers[length]; will not compile because length is a non-constant. Use std::vector<int> numbers(length); instead.
And that's about it.
#include <iostream>
#include <vector>
#include <time.h>
int main()
{
std::srand(time(0));
int j, flag = 0;
int temp;
for (int t = 0; t < 50; t++)
{
int length = std::rand() % 20 + 1;
std::cout << "length is " << length << std::endl;
std::vector<int> numbers(length);;
for (int i = 0; i < length; i++)
{
numbers[i] = std::rand();
std::cout << numbers[i] << std::endl;
}
for (j = 0; (j <= length); j++)
{
for (int i = 0; i < (length - 1); i++)
{
if (numbers[i + 1] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temp;
flag++;
}
}
}
std::cout << "Number of Swaps : " << flag << std::endl;
}
}

copy one array to another without duplicates C++

The problem is that, I have an array of 10 integers, having some duplicates. The task is to copy this array to another array of same size, but without duplicate values. That is, read one element from array1, compare it with all the elements in array2, if it's already in array2, just skip it or print that it's already in array2, go to second element of array1, and repeat the process.
Now, I've tried this but don't know where's the problem:
#include <iostream>
using namespace std;
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
break;
}
}
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
array1 has 10 elements and array2 has 11, so right away the requirements haven't been met. Presumably, having 11 elements was a workaround for using incorrect index values in the for loops; the index should run from 0 to 9, not from 1 to 10.
When you add an element to the second array, you should only check it value against the elements that have already been added, not against the values in the entire array.
Finally, there's an underspecification. Once you've eliminated duplicates, you have fewer than 10 elements; array2 has 10 elements; what values should the extra elements have?
std::unique_copy is your friend:
http://en.cppreference.com/w/cpp/algorithm/unique_copy
remember to sort the source array first
In C++, break immediately ends one loop structure, and starts execution immediately after it. Thus, the line array2[i] = array1[i-1]; executes redardless of whether the inner for loop finds a duplicate. One solution is to set a variable indicating that the value is a duplicate:
int main() {
int temp;
bool isDuplicate; //added this line
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
isDuplicate=false;//added this line
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
isDuplicate=true; //added this line
break;
}
}
if(!isDuplicate) //added this line
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl; system("pause"); }
Alternatively (though many programmers would disagree with this practice) you could use a goto statement instead of a break statement:
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
goto duplicate; //added this line
}
}
array2[i] = array1[i-1];
//added next line
duplicate:
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
You could use a std::set to ensure uniqueness for you.
http://en.cppreference.com/w/cpp/container/set
You have three approaches:
compare each element one by one (O(N^2) performance)
sort your reference array and use a binary search to determine if the element exists (O(N*lnN) performance)
create a lookup hash (O(1) performance)
I can see two main sources of problems in your code: 1) the break statement, as it is, does not solve the problem of differentiating between the case when duplicate is found, and when the element in array1 should be added to array2. 2) There is no counter which would store the number of elements inserted so far into array2, this way they could not be copied to array2 next to each other. The code which fixes both is:
#include <iostream>
using namespace std;
int main()
{
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[10];
int array2_elements_inserted = 0;
for(int i = 0; i < 10; i++)
{
int temp = array1[i];
bool isDuplicate = false;
for(int j = 0; j < array2_elements_inserted; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
array2[array2_elements_inserted] = temp;
++array2_elements_inserted;
}
}
for(int k = 0; k < array2_elements_inserted; k++)
cout << array2[k] << " " << endl;
// system("pause");
}
Output:
10
2
5
4
6
9
8
First of all, use dynamic containers. Especially have a look at those provide by
the standard library, e.g. std::vector. Second, you should use a set data structure
to keep track of the elements you have seen before, e.g., std::set.
Then it's just an iteration on the input array and appending new elements to the
output array.
Here's an example:
#include <vector>
#include <set>
#include <iostream>
int main() {
// define and print input data
std::vector<int> v1 = {10,2,5,4,10,5,6,9,8,10};
for (int i : v1)
std::cout << i << " ";
std::cout << "\n";
// this will soon contain the output data
std::vector<int> v2;
// a set to keep track of the already seen elements
std::set<int> set;
// iterate the input array using range-based for loop
for (int i : v1) {
// check for duplicates
if (set.find(i) == set.end()) {
// first occurrence, insert to set, append to output data
set.insert(i);
v2.push_back(i);
}
else {
// seen before, do nothing
}
}
// print output data
for (int i : v2)
std::cout << i << " ";
std::cout << "\n";
}
The output:
$ g++ test.cc -std=c++11 && ./a.out
10 2 5 4 10 5 6 9 8 10
10 2 5 4 6 9 8
For reference:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/language/range-for
http://en.cppreference.com/w/cpp/container/set
http://en.cppreference.com/w/cpp/container/set/find

How to avoid copying values to a separate array?

I have the following program that computes the "partial sum" of an array. For example, if I input the consecutive integers 1, 1, 1, 1 through std::cin my program will calculate the result into an array as 1, 2, 3, 4.
#include <iostream>
int main()
{
int orig[10], copy[10];
std::cout << "please enter 10 numbers:" << std::endl;
for (int i = 0; i < 10; i++)
{
std::cin >> orig[i];
}
for (int i = 0; i < 10; ++i)
{
int sum = 0;
for (int k = i; k >= 0; --k)
{
sum += orig[k];
}
copy[i] = sum;
}
std::cout << "the ascending order is:\n" << endl;
for (int i = 0; i < 10; ++i)
std::cout << copy[i] << std::endl;
}
My problem is that I would like for there to be a way to do this without copying the value into another array. So far I haven't figured out how. As you can see, in the above code I have an integer array named copy into which I put the sum into its indicies. I know this can be done using std::vector and partial_sum but I would rather not use it as it does not allow me to fully understand how this works.
Any ideas? Thanks.
You don't need the two nested for loops. Move the initialization of sum out of the for loop to keep track of the sum as you iterate over orig. The simply overwrite the values in orig with sum as you go.
In psuedocode:
sum = 0
for each index i in array:
sum += array[i]
array[i] = sum
I know you don't want to use partial_sum, but here it is in all its simplicity:
#include <iostream>
#include <iterator>
#include <numeric>
int main()
{
using namespace std;
partial_sum(istream_iterator<int>(cin),
istream_iterator<int>(),
ostream_iterator<int>(cout, "\n"));
}
Code here.
Can't you print this out in the process without storing it?
sum = 0 ;
for ( int i = 0 ; i < 10 ; i++ )
{
sum += orig[ i ] ;
std::cout << sum << "\n" ;
}