How to print a two dimensional array in cocos2dx - c++

I have a two-dimensional array that I want to print to the output of visual studio to see the result each time I modify that, I tried using std::cout and it does not work, if I use CCLOG the function will automatically write a newline each time it's called that and it's not a two-dimensional array pretty solution, I also tried CClog not sure what's the difference with CCLOG but this time it even give a compiling error :(
like I want the output be:
1,2,4,4,5
5,5,4,3,0
4,4,4,4,7
6,6,6,6,6
Here is what I tried:
void HelloWorld::PrintBrickArray() {
CCLOG("will print brick array");
std::cout << "===Begin of Array ====" << std::endl;
for (int i = 0; i < MATRIX_Y; i++) {
for (int j = 0; j < MATRIX_X; j++) {
//CCLog("%d", this->brickArray[i][j]);
std::cout << this->brickArray[i][j] << ' ';
}
std::cout << std::endl;
}
std::cout << "*****END OF Array *****" << std::endl;
std::cout.flush();
}
How to do that with coco2dx?

CCLOG or cocos2d::log uses the Visual Studio's Debug windows, which is different to write to console where std::cout works.
Therefore, there are two ways to get rid of your problem: writing to console using std::cout or writing to output windows using different methods than CCLOG
First choice, you have to change your project type from Win32 Application Project to Win32 Console Project. This is kind of going around with Visual Studio stuffs, and in most cases, your project is created automatically via cocos2d's console. You can see this post. I'm not recommend this way IMO.
Second choice, use your own code to write to output which discussed here.
There is another way that you can use std::string and std::ostringstream to "print" your variables to buffer, and then just print your string to output windows via CCLOG
CCLOG is a little bit wrapping the code to make it convenience where we log resources checking, errors, file processing, etc which usually occur when run time. If not in those cases, you should probably set break points to view what the values are instead.
Edited: Since you chose the second approach, I would recommend using std::ostringstream than sprintf, and using CCLog instead of OutputDebugString (because you just print it out and independent OS, no need extra arguments)
Here is an example code:
#include <vector>
#include <sstream> // for ostringstream
#include <Windows.h> // for OutputDebugStringA
using namespace std;
int main(void)
{
// Assuming that you have this 2d array
vector< vector<int> > arr2d;
arr2d.push_back({ 2,2,1,4 });
arr2d.push_back({ 2,4,1,5 });
arr2d.push_back({ 2,4,7,2 });
arr2d.push_back({ 3,2,0,1 });
ostringstream buffer;
for (int i = 0; i < arr2d.size(); i++)
{
for (int j = 0; j < arr2d[i].size(); j++)
{
buffer << arr2d[i][j] << '\t';
}
buffer << endl;
}
// Assuming that you use OutputDebugString for windows-only
//OutputDebugStringA(buffer.str().c_str());
// I recommend this
cocos2d::log(buffer.str().c_str());
return 0;
}
Now, buffer works nearly the same as cout, it just "print" to buffer instead, then you can get one using str(). But cocos2d::log use C-style string, so c_str() will get rid of the problem
See more about std::ostringstream here

Related

Declaring a vector throws a runtime error in NetBeans

I'm trying to learn about vectors in C++, but just trying to declare one throws a runtime error in NetBeans.
Error: Run failed (exit value -1, 073, 741, 511, total time 51 ms)
PS: The code works perfectly in Eclipse.
#include <iostream>
#include <vector>
using namespace std;
int main() {
// create a vector to store int
vector<int> vec;
int i;
// display the original size of vec
cout << "vector size = " << vec.size() << endl;
// push 5 values into the vector
for (i = 0; i < 5; i++) {
vec.push_back(i);
}
// display extended size of vec
cout << "extended vector size = " << vec.size() << endl;
// access 5 values from the vector
for (i = 0; i < 5; i++) {
cout << "value of vec [" << i << "] = " << vec[i] << endl;
}
// use iterator to access the values
vector<int>::iterator v = vec.begin();
while (v != vec.end()) {
cout << "value of v = " << *v << endl;
v++;
}
return 0;
}
I have tested on my system (latest GCC and NB dev build) and it works without any problem. The desired output is shown. It also runs fine from command line.
Therefore I assume it's more a configuration or system related problem. But without any further informations it's impossible to find the root cause.
More information please:
What OS / Environment are you using?
What Compiler (and versions) do you have?
What version of Netbeans do you use?
Do other project's work?
Here's some first aid you can try:
Create a new C++ Project (C++ Application). It already includes a blank main() function. Run this and check if there's still an error
Create a simple .cpp file and build it from command line (don't involve any IDE). Does it work this way?
Build and your source file without IDE. From Commandline: g++ <your filename>.cpp
Review your compiler settings (Tools -> Options -> C/C++ at Build Tools). Especially use the Version button and check if everything is right.
Windows only: Make sure you have the correct make executable selected in the compiler settings
Have a look at the IDE's log (View -> IDE Log). Are there any problems mentioned?
Run in Debug without any breakpoint. This is going to stop the execution on any runtime error.

Integer to string conversion issues

I am experiencing a few problems with Crypto++'s Integer class. I am using the latest release, 5.6.2.
I'm attempting to convert Integer to string with the following code:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I get the same thing when I output directly to the console:
std::cout << "Dec: " << i << std::endl; // Same result
Additionally, I cannot get precision or scientific notation working. The following will output the same results:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
On top of all of this, sufficiently large numbers breaks the entire thing.
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
Ultimately I'm trying to get something where I can work with large Integer numbers, and can output a string in scientific notation. I have no problems with extracting the Integer library or modifying it as necessary, but I would prefer working with stable code.
Am I doing something wrong, or is there a way that I can get this working correctly?
I'm attempting to convert Integer to string with the following code:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I can't reproduce this with Crypto++ 5.6.2 on Visual Studio 2010. The corrupted output is likely the result of some other issue, not a bug in Crypto++. If you haven't done so already, I'd suggest trying to reproduce this in a minimal program just using CryptoPP::Integer and std::cout, and none of your other application code, to eliminate all other possible problems. If it's not working in a trivial stand-alone test (which would be surprising), there could be problems with the way the library was built (e.g. maybe it was built with a different C++ runtime or compiler version from what your application is using). If your stand-alone test passes, you can add in other string operations, logging code etc. until you find the culprit.
I do notice though that you're using std::ostrstream which is deprecated. You may want to use std::ostringstream instead. This Stack Overflow answer to the question "Why was std::strstream deprecated?" may be of interest, and it may even the case that the issues mentioned in that answer are causing your problems here.
Additionally, I cannot get precision or scientific notation working.
The following will output the same results:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
std::setprecision and std::scientific modify floating-point input/output. So, with regular integer types in C++ like int or long long this wouldn't work either (but I can see that especially with arbitrary-length integers like CryptoPP:Integer being able to output in scientific notation with a specified precision would make sense).
Even if C++ didn't define it like this, Crypto++'s implementation would still need to heed those flags. From looking at the Crypto++ implementation of std::ostream& operator<<(std::ostream& out, const Integer &a), I can see that the only iostream flags it recognizes are std::ios::oct and std::ios::hex (for octal and hex format numbers respectively).
If you want scientific notation, you'll have to format the output yourself (or use a different library).
On top of all of this, sufficiently large numbers breaks the entire
thing.
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
That will actually calculate i^(2^16) = i^65536, not i^16, because on each loop you're multiplying i with its new intermediate value, not with its original value. The actual result with this code would be 268,140 digits long, so I expect it's just taking Crypto++ a long time to produce that output.
Here is the code adjusted to produce the correct result:
CryptoPP::Integer i("12345");
CryptoPP::Integer i_to_16(1);
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i_to_16 *= i;
}
std::cout << i_to_16 << std::endl;
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I suspect what you presented is slighty simplified from what you are doing in real life. I believe the problem is related to LOGDEBUG and the ostringstream. And I believe you are outputting char*'s, and not string's (though we have not seen the code for your loggers).
The std::string returned from oss.str() is temporary. So this:
LOGDEBUG(oss.str());
Is slighty different than this:
string t(oss.str());
LOGDEBUG(t);
You should always make a copy of the string in an ostringstream when you intend to use it. Or ensure the use is contained in one statement.
The best way I've found is to have:
// Note: reference, and the char* is used in one statement
void LOGDEBUG(const ostringstream& oss) {
cout << oss.str().c_str() << endl;
}
Or
// Note: copy of the string below
void LOGDEBUG(string str) {
cout << str.c_str() << endl;
}
You can't even do this (this one bit me in production):
const char* msg = oss.str().c_str();
cout << msg << endl;
You can't do it because the string returned from oss.str() is temporary. So the char* is junk after the statement executes.
Here's how you fix it:
const string t(oss.str());
const char* msg = t.c_str();
cout << msg << endl;
If you run Valgrind on your program, then you will probably get what should seem to be unexplained findings related to your use of ostringstream and strings.
Here is a similar logging problem: stringstream temporary ostream return problem. Also see Turning temporary stringstream to c_str() in single statement. And here was the one I experienced: Memory Error with std:ostringstream and -std=c++11?
As Matt pointed out in the comment below, you should be using an ostringstream, and not an ostrstream. ostrstream has been deprecated since C++98, and you should have gotten a warning when using it.
So use this instead:
#include <sstream>
...
std::ostringstream oss;
...
But I believe the root of the problem is the way you are using the std::string in the LOGDEBUG function or macro.
Your other questions related to Integer were handled in Softwariness's answer and related comments. So I won't rehash them again.

Run std::function getted by binary read

I'm developing a application and my idea is store "apps" in files, like executables. Now i have that:
AppWriter.c
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} CODED;
void RANDOMFUNC()
{
srand(time(NULL));
for(int i = 0; i < 40; i++)
CODED.RandomStuff.push_back(rand() % 254);
}
void LOGARRAY()
{
for(int i = 0; i < CODED.RandomStuff.size(); i++)
std::cout << "["<< i + 1 <<"]: "<< CODED.RandomStuff[i] << std::endl;
}
void PROGRAMMAIN()
{
std::cout << "Hello i call random function!" << std::endl;
CODED.Functions[0]();
CODED.Functions[1]();
}
void main()
{
CODED.MAIN = PROGRAMMAIN;
CODED.Functions.push_back(RANDOMFUNC);
CODED.Functions.push_back(LOGARRAY);
std::cout << "Testing MAIN" << std::endl;
CODED.MAIN();
FILE *file = fopen("TEST_PROGRAM.TRI","wb+");
fwrite(&CODED,sizeof(CODED),1,file);
fclose(file);
std::cout << "Program writted correctly!" << std::endl;
_sleep(10000);
}
AppReader.c
#include <iostream>
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} DUMPED;
void main()
{
FILE *file = fopen("TEST_PROGRAM.TRI","rb+");
fseek(file,0,SEEK_END);
int program_len = ftell(file);
rewind(file);
fread(&DUMPED,sizeof(PROGRAM),1,file);
std::cout
<< "Function array size: " << DUMPED.Functions.size() << std::endl
<< "Random Stuff Array size: " << DUMPED.RandomStuff.size() << std::endl;
DUMPED.MAIN();
}
When i run AppReader the functions dont work(Maybe why std::function it's like void pointers?), but in arrays or if i add variables i can see with debugger the data are storaged correctly (for that i tryed the vector of functions), but whatever doesn't work throw's me error on functional file. ¿Any ideas how i can do that?
This is never going to work. At all. Ever. std::function is a complex type. Binary reads and writes don't work for complex types. They never can. You would have to ask for functions in a pre-defined serializable format, like LLVM IR.
Your problem is that you're storing information about functions that exist in one executable, then trying to run them in a separate executable. Other than that, your code does work, but as DeadMG says, you shouldn't be storing complex types in a file. Here's how I modified your code to prove that your code works if run within a single executable:
#include <iostream>
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} CODED;
void RANDOMFUNC()
{
srand(time(NULL));
for(int i = 0; i < 40; i++)
CODED.RandomStuff.push_back(rand() % 254);
}
void LOGARRAY()
{
for(int i = 0; i < CODED.RandomStuff.size(); i++)
std::cout << "["<< i + 1 <<"]: "<< CODED.RandomStuff[i] << std::endl;
}
void PROGRAMMAIN()
{
std::cout << "Hello i call random function!" << std::endl;
CODED.Functions[0]();
CODED.Functions[1]();
}
int main()
{
CODED.MAIN = PROGRAMMAIN;
CODED.Functions.push_back(RANDOMFUNC);
CODED.Functions.push_back(LOGARRAY);
std::cout << "Testing MAIN" << std::endl;
CODED.MAIN();
FILE *file = fopen("TEST_PROGRAM.TRI","wb+");
fwrite(&CODED,sizeof(CODED),1,file);
fclose(file);
std::cout << "Program writted correctly!" << std::endl;
// _sleep(10000);
std::cout << "---------------------\n";
file = fopen("TEST_PROGRAM.TRI","rb+");
fseek(file,0,SEEK_END);
int program_len = ftell(file);
rewind(file);
fread(&CODED,sizeof(PROGRAM),1,file);
std::cout
<< "Function array size: " << CODED.Functions.size() << std::endl
<< "Random Stuff Array size: " << CODED.RandomStuff.size() << std::endl;
CODED.MAIN();
}
The problem is not that you're storing complex types via binary read/write, per se. (Although that is a problem, it's not the cause of the problem you posted this question about.) Your problem is that your data structures are storing information about the functions that exist in your 'writer' executable. Those same functions don't even exist in your 'reader' executable, but even if they did, they likely wouldn't be at the same address. Your data structures are storing, via std::function, pointers to the addresses where the functions exist in your 'writer' executable. When you try to call these non-existent functions in your 'reader' executable, your code happily tries to call them but you get a segfault (or whatever error your OS gives) because that's not the start of a valid function in your 'reader' executable.
Now with regard to writing complex types (e.g. std::vector) directly to a file in binary format: Doing so "works" in the sample code above only because the binary copies of the std::vectors have pointers that, once read back in, still point to valid data from the original std::vectors which you wrote out. Note that you didn't write the std::vector's actual data, you only wrote their metadata, which probably includes things like the length of the vector, the amount of memory currently allocated for the vector, and a pointer to the vector's data. When you read that back, the metadata is correct except for one thing: Any pointers in it are pointing to addresses that were valid when you wrote the data, but which may not be valid now. In the case of the sample code above, the pointers end up pointing to the same (still valid) data from the original vectors. But there's still a problem here: You now have more than one std::vector that thinks they own that memory. When one of them is deleted, it will delete the memory that the other vector expects to still exist. And when the other vector is deleted, it will cause a double-delete. That opens the door to all kinds of UB. E.g. that memory could have been allocated for another purpose by that time, and now the 2nd delete will delete that other purpose's memory, or else the memory has NOT been allocated for another purpose and the 2nd delete may corrupt the heap. To fix this, you'd have to serialize out the essence of each vector, rather than their binary representation, and when reading it back in, you'd have to reconstruct an equivalent copy, rather than simply reconstitute a copy from the binary image of the original.

ostringstream SOMETIMES causes a crash

So I wrote an implementation of an ArrayList over the summer, and I have a toString method within which I use an ostringstream object to tack on strings and then output them.
the method is below:
template<class T>
std::string ArrayList<T>::toString() {
std::ostringstream streamOut;
streamOut << "(";
for (int i = 0; i < size; i++) {
streamOut << array[i];
if (i != (size - 1)) {
streamOut << ", ";
}
}
streamOut << ")\n";
std::string returnString = streamOut.str();
return returnString;
}
The problem is that when I run this program it sometimes crashes on the line in the above method:
streamOut << "(";
I tried adding a flush statement at the end but that didn't do the trick...I really have no idea what could be wrong here.
I think this issue may be related but I can't be sure....
https://stackoverflow.com/questions/8250851/big-ostringstream-causes-application-crash
EDIT:
I forgot to mention, that I am using eclipse for development, and I have been unable to get a crash of the program to occur when I run it in eclipse. It's only when I run the exe generated via windows or the command line that it crashes
I think it crashed because somewhere before this method incorrectly free the memory.

Trying to initialize a list with values but not working when I use a variable to create the size

This is my second time using C++ and I'm trying to port some Java code I made but am having trouble understanding some behavior. I have a list of data and want to create another list of the same size but the values are default to zero(in Java I use Arrays.fill(list, 0); after creating it). When I try to do something similar in C++ I get variable-sized object 'list1' may not be initialized
Here's a code to better example:
#include <iostream>
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace std;
using namespace boost::assign;
int main()
{
cout << "Hello World!" << endl;
vector<short> data;
data += -40, -30,-10, 20, 50;
//int coeff [data.size()];
cout << "data array size is " << data.size() << endl;
short list1 [data.size()] = {0}; //does not work
for (int i =0; i<data.size(); i++) {
cout << "data is " << list1[i] << endl;
}
cout << "********** try 2 **************" << endl;
//this works if I use a actual number to create the list but I want to declare it at runtime
short list2 [5] = {0};
for (int ii=0;ii<5;ii++) {
cout << "data is " << list2[ii] << endl;
}
return 0;
}
Like I mentioned, I'm completely green when I comes to C++ (I have read a book and done a few tutorials) so I may be doing something completely wrong. In the event I cannot do this at runtime and only at compile time, is there something else I can use to get the same result?
c++ does not have dynamically sized arrays, so this is illegal:
short list1 [data.size()];
but you can use a vector:
std::vector<short> list1(data.size(),0);
That creates a vector of the same length as data, full of zeroes.
If you want an array whose size is determined at runtime, you'll have to allocate it.
short * list1 = new short[data.size()];
//do stuff
delete [] list1; //we don't want to leak
You typically want to avoid naked pointers whenever possible, so the cleaner solution is what juanchopanza suggested and try to use std::vector.
The equivalent of Arrays.fill(list, 0); for a C++ vector looks like std::fill(list.begin(), list.end(), 0);
You can also simply declare a std::vector<short> list1(data.size()); to create it with zero initialized values or with a specific value std::vector<short> list1(data.size(), 0);