0

I am new to C++ and am trying to make a function that takes an array of numbers and converts those numbers into the ASCII character, i.e. int to string. When I try to output the string however I get random characters. I have searched tutorials and a suggestion was that I should add a string terminator, which I did, but it doesn't seem to fix it and I can't find an answer that would solve this.

i.e. I want the below code to print "Hello".

#include <iostream>
#include <string>

char* intToString(int* array, int size)
{
    char string[size + 1];
    string[size] = '\0';
    for (int i = 0; i <= size; i++)
        string[i] = array[i];

    return string;
}


int main()
{
    int my_array[5] = {72, 101, 108, 108, 111};
    int size = 5;
    std::cout << intToString(my_array, size);

    return 0;
}
3
  • you're missing something along the lines of string[i] = itoa(array[i]); since the random characters you get aren't the character representation of the numbers you want. Commented Apr 26, 2018 at 12:51
  • You include #include <string> but don't use std::string (C++ string). Commented Apr 26, 2018 at 12:53
  • In your code it should be i<size since array[size] is undefined. Commented Apr 26, 2018 at 15:12

5 Answers 5

1

char * is not a string. It's a pointer to char. In your case you get random characters because you return pointer to local string which is destroyed after the call. Use std::string or, if you want arrays that much, you can get proper copy semantics from std::array.

Sign up to request clarification or add additional context in comments.

2 Comments

My "string terminator" was useless too, so I removed that. Thank you
@AndrewCina: No, you needed that for the <<. Unfortunately you implemented it wrong :)
1

Your code shouldn't even compile because size+1 isn't a compile time constant value, changing the line

char string[size+1];

to

char string*=new char[size+1]

should make your code compile and give correct output because you create your array on the heap (so the array is not destroyed when the function returns). However that means that you have to destroy delete it yourself.

So it's a good idea to change

std::cout << intToString(my_array, size);

To

char *string=intToString(my_array, size);
std::cout << string;
delete[] string;

Though note that others answers are right that you should use std::string and std::vector instead of char arrays and arrays in general, what you're doing right now is mixing c with c++.

6 Comments

Thanks, is there more information somewhere on not mixing c with c++? I don't fully understand the taboo I've broken with mixing them.
One of the primary design goals of C++ is its compatibility with C. This means that as a developer you have to decide when to use C types like plain arrays or C++ (better: STL) types like std::vector. For example if you are developing in C++ for certain microcontroller architectures it can even be forbidden to use any of the STL types like std::vector or std::string as there is no dynamic heap memory and/or the performance of these types does not meet the very strict requirements in these areas. Hence the choice of types and therefore style does very much depend on your environment.
I recommend this question in general there's not much wrong with it but for beginners it's better to either grasp C or C++. because std::string is not the same as char[] so if you use one function with char array and second with std string you're going to have a bad time. Later on you might mix C with C++ when you get familiar enough with C++.
Thanks both - I looked at that question and it’s definitly useful, but, not to go off topic too much, when am I actually using c in c++? When I’m trying to write code that can be handled easier by the STL? For example, as far as any tutorial on c++ that I’ve done shows, arrays appear to be fair game. Hope that makes sense and isn’t a bad question.
@AndrewCina Arrays certainly have their uses in c++, if you want a chess board for example it's better to use an array int a[8][8] then to use a vector. I don't think you should focus that much on it really.
|
0

As close as possible to your initial attempt:

#include <iostream>
#include <string>
std::string intToString(int my_array[], int size)
{
    // just declare a variable of type std::string instead of char string[size+1]
    // there's no need to define a size as this std::string will grow dynamically
    // there's also no need to add a delimiter as std::string takes 
    // care of this itself
    std::string string;
    for (int i = 0; i < size; i++) {
        // this appends an integer representing an (ASCII) codepoint 
        // to an initially empty std::string
        string += my_array[i];
        // this won't work as string is initially empty
        // so you can't access the element at index 0 
        // string[i] = my_array[i];
    }
    return string;
}
int main()
{
    const int size = 5;
    int my_array[] = { 72, 101, 108, 108, 111 };
    std::cout << intToString(my_array, size) << std::endl;
    return 0;
}

Notice the differences to your solution pointed out in the comments.

1 Comment

While it's technically true that the buffer managed by a std::string is going to be terminated by a '\0' (because this is the only decent way to implement it given the requirements of op[]), instead of saying "[string] takes care of [the delimiter] itself" it's more logically correct to say "string doesn't have a delimiter because it tracks content length separately".
0

There is still a problem in the updated solution that you have written.

  • You should still declare the string array with size+1 and need to make the last element as \0.
  • Or you can use the std::string.

Here is C++ way of doing it, it can be further shortened, but this is as close as it can get to your code.

#include <iostream>
#include <string>
#include <vector>

std::string intToString(const std::vector<int>& vec)
{
    std::string ans;
    for (auto& each : vec)
        ans += char(each);
    return ans;
}


int main()
{
    std::vector<int> vec{72, 101, 108, 108, 111};
    std::cout << intToString(vec);
    return 0;
}

3 Comments

Some new language for me to explore there - thank you. So I understand correctly that my code (not shortened) would be corrected by just declaring the string with std::string instead of char? Is there a reason for this?
Its not enough to just declare string of type std::string. See my answer.
As I have mentioned, you can use char[size+1], but it's working by chance in your case.
0

In C++11 std::to_string is preferable. If you need your converter function for more than one type and/or datacontainer you can use a template function like this

#include <iostream>
#include <string>
#include <vector>
#include <array>

template <typename T>
std::string toString(const T & items) {
    std::string str;
    for (const auto & item : items) {
        str += std::to_string(item);
    }

    return str;
}


int main() {
    const std::vector<int> my_vector {102, 101, 108, 108, 111};
    std::cout << toString(my_vector);


    std::cout << std::endl;

    const std::array<double,5> my_array {102, 101, 108, 108.5, 111.0};
    std::cout << toString(my_array);
    return 0;
}

1 Comment

The question's author specified that he want to convert ints to corresponding ascii chars not their string representation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.