I try to create 2 matrices: 1 of char* and 1 of THAR*. But for TCHAR* matrix instead of strings I get addresses of some kind. What's wrong?
Code:
#include <tchar.h>
#include <iostream>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
//char
const char* items1[2][2] = {
{"one", "two"},
{"three", "four"},
};
for (size_t i = 0; i < 2; ++i)
{
cout << items1[i][0] << "," << items1[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
//TCHAR attempt
const TCHAR* items2[2][2] = {
{_T("one"), _T("two")},
{_T("three"), _T("four")},
};
for (size_t i = 0; i < 2; ++i)
{
cout << items2[i][0] << "," << items2[i][1] <<endl;
}
/*
Incorrect output:
0046AB14,0046AB1C
0046AB50,0046D8B0
*/
return 0;
}
To fix the issue we need to use wcout for Unicode strings. Using How to cout the std::basic_string<TCHAR> we can create flexible tcout:
#include <tchar.h>
#include <iostream>
using namespace std;
#ifdef UNICODE
wostream& tcout = wcout;
#else
ostream& tcout = cout;
#endif // UNICODE
int main(int argc, _TCHAR* argv[])
{
//char
const char* items1[2][2] = {
{"one", "two"},
{"three", "four"},
};
for (size_t i = 0; i < 2; ++i)
{
tcout << items1[i][0] << "," << items1[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
//TCHAR attempt
const TCHAR* items2[2][2] = {
{_T("one"), _T("two")},
{_T("three"), _T("four")},
};
for (size_t i = 0; i < 2; ++i)
{
tcout << items2[i][0] << "," << items2[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
return 0;
}
Related
I have this code:
#include <iostream>
#include <io.h>
#include <fcntl.h>
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
std::string t_prefix = "\u2554";
std::string t_middle = "";
std::string t_suffix = "\u2557\n\u2551";
int max_message_length = 33;
for (int i = t_middle.length(); i < max_message_length; i++) {
t_middle = "\u2550" + t_middle;
}
std::string complete_message = t_prefix + t_middle + t_suffix;
std::wcout << L"\u2554" << t_middle.c_str() << L"\u2557\n\u2551";
std::wcout << complete_message.c_str();
//std::wcout << L"\u2554\n";
}
The first wout line prints the first and last part right, the middle section prints out garbage because it does not have the L in it. (How do I use the L with a variable?)
The second wout line combines the prefix, message, and suffix prints out garbage since it needs the L switch to print properly? I find a million of examples of how to do it with straight hard coded text L"\u2554\u2550\u2550" ect ect but I wanted the program to be a little more flexible so the game boarder could be wider if so set.
This seems to work and do what I need it to do at least for windows:
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include <string>
int main()
{
_setmode(_fileno(stdout), _O_U8TEXT);
std::wstring t_prefix { L'\u2554' };
std::wstring t_suffix { L"\u2557\n\u2551" };
std::wstring t_middle;
const size_t max_message_length { 33 };
for (size_t i { t_middle.size() }; i < max_message_length; ++i)
{
t_middle += L'\u2550';
}
std::wstring complete_message { t_prefix + t_middle + t_suffix };
std::wcout << complete_message << '\n';
}
and this is suppose to work on linux:
#include <iostream>
int main()
{
std::string t_prefix = "╔";
std::string t_middle;
std::string t_suffix = "╗\n║";
int max_message_length = 33;
for (int i = t_middle.size(); i < max_message_length; ++i)
t_middle = "═" + t_middle;
std::string complete_message = t_prefix + t_middle + t_suffix;
std::cout << complete_message << '\n';
}
This question already has answers here:
c++ multiple definitions of a variable
(5 answers)
multiple definition error c++
(2 answers)
What exactly is One Definition Rule in C++?
(1 answer)
Closed 2 years ago.
I am attempting to compile my c++ code, and I continue getting the error:
/tmp/ccEsZppG.o:(.bss+0x0): multiple definition of `mailboxes'
/tmp/ccEZq43v.o:(.bss+0x0): first defined here
/tmp/ccEsZppG.o:(.bss+0xc0): multiple definition of `threads'
/tmp/ccEZq43v.o:(.bss+0xc0): first defined here
/tmp/ccEsZppG.o:(.bss+0x120): multiple definition of `semaphores'
/tmp/ccEZq43v.o:(.bss+0x120): first defined here
collect2: error: ld returned 1 exit status
Here is my code:
addem.cpp
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include "mailbox.h"
using namespace std;
void *sumUp(void *arg);
int main(int argc, char *argv[]) {
int numThreads, minThreads, maxInt, minInt;
if (argc < 3) {
cout << "Error: Need three arguments" << endl;
return 1;
}
numThreads = atoi(argv[1]);
maxInt = atoi(argv[2]);
minThreads = 1;
minInt = 1;
if (numThreads < 1) {
cout << "Cannot work with less than one thread\n"
<< "It's okay but do better next time!\n"
<< "We'll work with 1 thread this time.\n";
numThreads = minThreads;
} else if (numThreads > MAXTHREAD) {
cout << "Sorry, the max for threads is 10.\n"
<< "We'll work with 10 threads this time.\n";
numThreads = MAXTHREAD;
}
if (maxInt < 1) {
cout << "What do you want me to do? I can't count backwards!\n"
<< "I can barely count forwards! Let's make the max number\n"
<< "be 1 to save time\n";
maxInt = minInt;
}
struct msg outgoingMail[numThreads];
int divider = maxInt / numThreads;
int count = 1;
//initialize arrays (mailboxes, semaphores)
for (int i = 0; i < numThreads; i++) {
sem_init(&semaphores[i], 0, 1);
outgoingMail[i].iSender = 0;
outgoingMail[i].type = RANGE;
outgoingMail[i].value1 = count;
count = count + divider;
if (i = numThreads - 1) {
outgoingMail[i].value2 = maxInt;
} else {
outgoingMail[i].value2 = count;
}
}
for (int message = 0; message < numThreads; message++) {
SendMsg(message+1, outgoingMail[message]);
}
int thread;
for (thread = 0; thread <= numThreads; thread++) {
pthread_create(&threads[thread], NULL, &sumUp, (void *)(intptr_t)(thread+1));
}
struct msg incomingMsg;
int total = 0;
for (thread = 0; thread < numThreads; thread++) {
RecvMsg(0, incomingMsg);
total = total + incomingMsg.value1;
}
cout << "The total for 1 to " << maxInt << " using "
<< numThreads << " threads is " << total << endl;
return 0;
}
void *sumUp(void *arg) {
int index,total;
index = (intptr_t)arg;
struct msg message;
RecvMsg(index, message);
message.iSender = index;
message.type = ALLDONE;
total = 0;
for (int i = message.value1; i <= message.value2; i++) {
total += i;
}
SendMsg(0, message);
return (void *) 0;
}
mailbox.cpp
#include <stdio.h>
#include <iostream>
#include "mailbox.h"
using namespace std;
int SendMsg(int iTo, struct msg &Msg) {
if (safeToCall(iTo)) {
cout << "Error calling SendMsg" << endl;
return 1;
}
sem_wait(&semaphores[iTo]);
mailboxes[iTo] = Msg;
sem_post(&semaphores[iTo]);
return 0;
}
int RecvMsg(int iFrom, struct msg &Msg) {
sem_wait(&semaphores[iFrom]);
if (safeToCall(iFrom)) {
cout << "Error calling RecvMsg" << endl;
return 1;
}
mailboxes[iFrom] = Msg;
sem_post(&semaphores[iFrom]);
return 0;
}
bool safeToCall(int location) {
bool safe = !(location < 0 || location > MAXTHREAD + 1);
return safe;
//return true;
}
mailbox.h
#ifndef MAILBOX_H_
#define MAILBOX_H_
#define RANGE 1
#define ALLDONE 2
#define MAXTHREAD 10
#include <semaphore.h>
#include <pthread.h>
struct msg {
int iSender; /* sender of the message (0 .. numThreads)*/
int type; /* its type */
int value1; /* first value */
int value2; /* second value */
};
struct msg mailboxes[MAXTHREAD + 1];
pthread_t threads[MAXTHREAD + 1];
sem_t semaphores[MAXTHREAD + 1];
int SendMsg(int iTo, struct msg &Msg);
int RecvMsg(int iFrom, struct msg &Msg);
bool safeToCall(int location);
#endif
I am compiling the code with the command
g++ -o addem addem.cpp mailbox.cpp -lpthread
I have tried commenting out all of the function bodies in the source code to leave them as stub functions, and the same error occurs. The only way I have been able to compile the file is if I comment out the function bodies, and remove
#include "mailbox.h"
From at least one of the files. I feel it has to do with how I am initializing the arrays? But I cannot figure out a workaround.
I am having a problem in trying to serialize an array of unsigned char into file with GZIP compression using protobuf while playing with the library.
I think the problem might have to do with some of my syntax or misuse of API.
I have also tried std::fstream.
FYI, Windows 8.1 & VS2013 is the building environment.
scene.proto
syntax = "proto3";
package Recipe;
message Scene
{
repeated int32 imageData = 1 [packed=true];
}
source.cpp
#include <iostream>
#include <fstream>
#include <ostream>
#include <istream>
#include <string>
#include <cstdint>
#include "Scene.pb.h"
#include <google\protobuf\io\zero_copy_stream_impl.h>
#include <google\protobuf\io\gzip_stream.h>
int const _MIN = 0;
int const _MAX = 255;
unsigned int const _SIZE = 65200000;
unsigned int const _COMPRESSION_LEVEL = 10;
void randWithinUnsignedCharSize(uint8_t * buffer, unsigned int size)
{
for (size_t i = 0; i < size; ++i)
{
buffer[i] = _MIN + (rand() % static_cast<int>(_MAX - _MIN + 1));
}
}
using namespace google::protobuf::io;
int main()
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
Recipe::Scene * scene = new Recipe::Scene();
uint8_t * imageData = new uint8_t[_SIZE];
randWithinUnsignedCharSize(imageData, _SIZE);
for (size_t i = 0; i < _SIZE; i++)
{
scene->add_imagedata(imageData[i]);
}
std::cout << "scene->imagedata_size() " << scene->imagedata_size() << std::endl;
{
std::ofstream output("scene.art", std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
OstreamOutputStream outputFileStream(&output);
GzipOutputStream::Options options;
options.format = GzipOutputStream::GZIP;
options.compression_level = _COMPRESSION_LEVEL;
GzipOutputStream gzipOutputStream(&outputFileStream, options);
if (!scene->SerializeToZeroCopyStream(&gzipOutputStream)) {
std::cerr << "Failed to write scene." << std::endl;
return -1;
}
}
Recipe::Scene * scene1 = new Recipe::Scene();
{
std::ifstream input("scene.art", std::ifstream::in | std::ifstream::binary);
IstreamInputStream inputFileStream(&input);
GzipInputStream gzipInputStream(&inputFileStream);
if (!scene1->ParseFromZeroCopyStream(&gzipInputStream)) {
std::cerr << "Failed to parse scene." << std::endl;
return -1;
}
}
std::cout << "scene1->imagedata_size() " << scene1->imagedata_size() <<std::endl;
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
You seem to have a typo in your code. Compression level is according to documentation in range 0-9. You set incorrectly compression level to 10.
Your example is working for me when corrected to:
unsigned int const _COMPRESSION_LEVEL = 9;
What's the correct way to add a character array to a constant character array in C++?
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int pathSize = 0;
char* pathEnd = &argv[0][0];
while(argv[0][pathSize] != '\0') {
if(argv[0][pathSize++] == '/')
pathEnd = &argv[0][0] + pathSize;
}
pathSize = pathEnd - &argv[0][0];
char *path = new char[pathSize];
for(int i = 0; i < pathSize; i++)
path[i] = argv[0][i];
cout << "Documents Path: " << path + "docs/" << endl; // Line Of Interest
delete[] path;
return 0;
}
This code outputs:
Documents Path: �\
Using 'path' instead of '*path' will give me the compile error:
invalid operands of types ‘char*’ and ‘const char [6]’ to binary ‘operator+’
May I suggest using C++ to begin with, and (Boost) Filesystem for maximum benefits:
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
int main(int argc, const char *argv[])
{
const std::vector<std::string> args { argv, argv+argc };
path program(args.front());
program = canonical(program);
std::cout << (program.parent_path() / "docs").native();
}
This will use the platform's path separator, know how to translate 'funny' paths (e.g. containing ..\..\, or UNC paths).
Something like this should do it (totally untested):
const char* end = strrchr(argv[0], '/');
std::string docpath = end ? std::string(argv[0], end) : std::string(".");
docpath += '/docs/';
Your way:
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int pathSize = 0;
char* pathEnd = &argv[0][0];
while(argv[0][pathSize] != '\0') {
if(argv[0][pathSize++] == '/')
pathEnd = &argv[0][0] + pathSize;
}
pathSize = pathEnd - &argv[0][0];
char *path = new char[pathSize + 5]; //make room for "docs/"
for(int i = 0; i < pathSize; i++)
path[i] = argv[0][i];
char append[] = "docs/";
for(int i = 0; i < 5; i++)
path[pathSize+i] = append[i];
cout << "Documents Path: " << path << endl;
function_expecting_charptr(path);
delete[] path;
return 0;
}
Sane C way:
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
char* pathEnd = strrchr(argv[0], '/');
if (pathEnd == NULL)
pathEnd = argv[0];
int pathSize = (pathEnd-argv[0]) + 5; //room for "docs/"
char *path = new char[pathSize];
if (pathSize)
strncpy(path, argv[0], pathSize+1);
strcat(path, "docs/");
cout << "Documents Path: " << path << endl;
function_expecting_charptr(path);
delete[] path;
return 0;
}
C++ way:
#include <iostream>
#include <string>
int main(int argc, char** argv) {
std::string path = argv[0];
size_t sep = path.find('/');
if (sep != std::string::npos)
path.erase(sep+1);
else
path.clear();
path += "docs/";
std::cout << "Documents Path: " << path << endl;
function_expecting_charptr(path.c_str());
return 0;
}
Note that argv[0] holds an implementation defined value, and especially in *nix environments isn't guaranteed to hold anything useful. The first parameter passed to the program is found in argv[1].
I combined some of your guys' ideas into this compact code:
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char** argv) {
const string path_this = argv[0];
const string path = path_this.substr(0, strrchr(argv[0], '/') - argv[0] +1);
const string path_docs = path + "docs/";
cout << "Documents Path: " << path_docs << endl;
return 0;
}
To get the character array from this I can then run 'path_docs.c_str()'.
Credits: #MooingDuck, #MarkB, Google.
#include <iostream>
#include <string.h> // for strlen
#include <stdlib.h> // for atoi
#include <sstream>
void expand_combinations(const char *remaining_string, std::ostringstream& i, int remain_depth)
{
if(remain_depth==0)
{
std::cout << i.str() << std::endl;
return;
}
for(int k=0; k < strlen(remaining_string); ++k)
{
std::ostringstream l;
l << i.str();
l << remaining_string[k];
expand_combinations(remaining_string+k+1, l, remain_depth - 1);
}
return;
}
int main(int argc, char **argv)
{
std::ostringstream i;
if(argc<3) return 1;
expand_combinations(argv[1], i, atoi(argv[2]));
return 0;
}
How can this code be changed so that it doesn't use ostringstream?
The following is your code with string in place of ostringstream. Normally I'd refactor the code but since your question was pretty specific I'll leave it alone.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void expand_combinations(const char *remaining_string, string const & s, int remain_depth)
{
if(remain_depth==0)
{
std::cout << s << std::endl;
return;
}
for(int k=0; k < strlen(remaining_string); ++k)
{
string str(s);
str.append(1, remaining_string[k]);
expand_combinations(remaining_string+k+1, str, remain_depth - 1);
}
return;
}
int main(int argc, char **argv)
{
if(argc<3) return 1;
expand_combinations(argv[1], "", atoi(argv[2]));
return 0;
}