How can I combine two QStrings into one? - c++

I try to add two QStrings into one. I've read a lot about:
QString NAME = QString + QString
but this doesn't helps me here. Thats how my code look so far:
test.h
#ifndef TEST_H
#define TEST_H
#include <QString>
#include <QFile>
#include <QDir>
class Test
{
public:
void createProject(QString* p, QString*n);
};
#endif // TEST_H
test.cpp
#include "test.h"
#include <QFile>
#include <QString>
#include <QDir>
void Test::createProject(QString *p, QString *n)
{
QString result = p + n;
QDir dir(result);
if (dir.exists())
{
// ok
}
else
{
printf("Error!\n");
}
}
(ignore the code about checking if the directory exists, btw I use Qt 4.8.6)
So now when I try to compile, I get this error:
test.cpp: In member function 'void Test::createProject(QString*,
QString*)': test.cpp:8:21: error: invalid operands of types 'QString*'
and 'QString*' to binary 'operator+'
QString result = p + n;
How can I make this work? Also using += instead of + doesn't works here.
~ Jan

Indeed you are adding their address as p and n are pointer. try adding their value as:
QString result = *p + *n;

Related

How do I fix this c++ expected expression error?

I am making something in c++, it doesn't have any errors visible in Visual Studio code, but when I use g++ to be able to execute it, I get this error:
In file included from Main.cpp:6: In file included from ./Filechange/Filechange.hpp:1: ./Filechange/Filechange.cpp:14:24: error: expected expression
std::thread first ([&wtime,&f,&fn]() mutable {
^ Main.cpp:16:33: error: expected expression
OnFilechange("FileEvent", 0.5, [](char* txt){
^ 2 errors generated.
These are the files:
Main.cpp:
#include <lua.hpp>
#include <iostream>
#include <chrono>
#include <thread>
#include <stdio.h>
#include "Filechange/Filechange.hpp"
void wait(int seconds)
{
std::this_thread::sleep_for(std::chrono::seconds(seconds));
}
int main(int argc, char const *argv[])
{
lua_State *State = luaL_newstate();
OnFilechange("FileEvent", 0.5, [](char* txt){
std::cout << txt << std::endl;
});
lua_close(State);
return 0;
}
Filechange.cpp:
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <string>
#include <fstream>
char* StringToChar(std::string str){
char* Array = new char[str.length() + 1];
strcpy(Array,str.c_str());
return Array;
}
void OnFilechange(const char *f, float wtime, void (*fn)(char* txt)){
std::thread first ([&wtime,&f,&fn]() mutable {
std::ifstream file(f);
std::string str;
std::string filecontents;
while (std::getline(file,str)){
filecontents += str;
filecontents.push_back('\n');
}
char* LastContents = StringToChar(filecontents);
char* CurrentContents = StringToChar(filecontents);
while (true){
if (wtime != 0){
std::this_thread::sleep_for(std::chrono::milliseconds(int(wtime*1000)));
}
filecontents = "";
while (std::getline(file,str)){
filecontents += str;
filecontents.push_back('\n');
}
CurrentContents = StringToChar(filecontents);
if (strcmp(LastContents, CurrentContents) != 0){
LastContents = StringToChar(filecontents);
fn(StringToChar(filecontents));
}
}
});
}
Filechange.hpp:
#include "Filechange.cpp"
#ifndef FILECHANGE_HPP
#define FILECHANGE_HPP
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <string>
#include <fstream>
void OnFilechange(const char *f,float wtime,void (*fn)(char txt));
#endif
There's also a extension less file named FileEvent which will change in the runtime using other code files.
The Filechange.cpp and Filechange.hpp are in a folder named "Filechange"
This function:
void OnFilechange(const char *f, float wtime, void (*fn)(char* txt))
expects a function pointer, and a lambda in g++ is not implemented as a function pointer. Instead, you should declare the function to take a std::function, as in:
void OnFilechange(const char *f, float wtime, std::function<void(char *)> fn)
You may also need #include <functional> to get the declaration of std::function.
use -std=c++17 in g++ if possible as g++ defaulted to c++98

Undefined reference when compiling when using header and cpp file with templates in one of them

I've been trying to compile my project and I've encountered some problems when trying so. The error in particular that appears is:
[build] /usr/bin/ld: CMakeFiles/robot_control.dir/main.cpp.o:(.data.rel.ro._ZTVN4comm15cameraInterfaceE[_ZTVN4comm15cameraInterfaceE]+0x10): undefined reference to `comm::Interface<cv::Mat>::callbackMsg()'
My project is organized right now as it follows:
-${HOME_WORKSPACE}
|-main.cpp
|-src
|-communication.cpp
|-communication.hpp
The header file (communication.hpp) is:
#include <opencv2/opencv.hpp>
#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <algorithm>
#ifndef COMM_GUARD
#define COMM_GUARD
namespace comm
{
struct lidarMsg
{
float angle_min, angle_increment, range_min, range_max;
int nranges, nintensities;
std::vector<int> ranges;
};
template <typename T>
class Interface
{
public:
Interface() : received{false} {};
virtual void callbackMsg();
bool receptionAccomplished()
{
return this -> received;
}
T checkReceived()
{
return this -> elementReceived;
}
protected:
bool received;
T elementReceived;
};
class cameraInterface : public Interface<cv::Mat>
{
public:
void callbackMsg(ConstImageStampedPtr &msg);
};
class lidarInterface : public Interface<lidarMsg>
{
public:
void callbackMsg(ConstLaserScanStampedPtr &msg);
};
}
#endif
The source file (communication.cpp) is:
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
#include "communication.hpp"
#ifndef COMM_CPP_GUARD
#define COMM_CPP_GUARD
namespace comm
{
void cameraInterface::callbackMsg(ConstImageStampedPtr &msg)
{
std::size_t width = msg->image().width();
std::size_t height = msg->image().height();
const char *data = msg->image().data().c_str();
cv::Mat im(int(height), int(width), CV_8UC3, const_cast<char *>(data));
im = im.clone();
cv::cvtColor(im, im, cv::COLOR_RGB2BGR);
this->elementReceived = im;
received = true;
}
void lidarInterface::callbackMsg(ConstLaserScanStampedPtr &msg) {
this->elementReceived.angle_min = float(msg->scan().angle_min());
this->elementReceived.angle_increment = float(msg->scan().angle_step());
this->elementReceived.range_min = float(msg->scan().range_min());
this->elementReceived.range_max = float(msg->scan().range_max());
this->elementReceived.nranges = msg->scan().ranges_size();
this->elementReceived.nintensities = msg->scan().intensities_size();
for (int i = 0; i < this->elementReceived.nranges; i++)
{
if (this->elementReceived.ranges.size() <= i)
{
this->elementReceived.ranges.push_back(std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max));
}
else
{
this->elementReceived.ranges[i] = std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max);
}
}
}
}
#endif
The main file(main.cpp) includes the following header:
#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
#include <stdlib.h>
#include "src/communication.hpp"
I included the part of the #ifndef /#define /#endif since it is a solution that I found to this kind of problem in other problem. I've been toggling the CMakeLists.txt file but still no solution that could solve this error.
You can't do this:
virtual void callbackMsg();
You have to actually provide the implementation for all template methods within the .h file.

Qt5 Unidentified reference to QInputDialog and QMessageBox.. ERROR

I am busy with my university assignment, i'm new to Qt, C++ and i am required to:
Define and implement the Address class in separate header and source files
I am getting confused with Qt4 and Qt5 as the prescribed text book gives all examples in Qt4 yet we are required to code with Qt5.
I keep getting errors and the latest error is :
error: undefined reference to
Dialog7getTextEP7QWidgetRK7QStringS4_N9QLineEdit8EchoModeES4_
Pb6QFlagsIN2Qt10WindowTypeEES8_INS9_15InputMethodHintEE'
error: undefined reference to
MessageBox11informationEP7QWidgetRK7QStringS4_6QFlagsINS_
14StandardButtonEES6
collect2.exe:-1: error: error: ld returned 1 exit status
I am very confused and stuck, please if anyone can steer me in the right direction i would greatly appreciate it, This is my code so far:
Header File:
#ifndef ADDRESS_H_
#define ADDRESS_H_
#include <QString>
#include <QFile>
#include <QStringList>
#include <QtCore>
QTextStream cout(stdout);
QTextStream cerr(stderr);
class Address{
public:
Address();
void setLines(QString ad, QString sep);
QString getPostalCode() const;
QString toString(QString sep) const;
static bool isPostalCode(QString pc);
private:
static QStringList lines;
};
#endif // ADDRESS_H_
Main File:
#include "address.h"
#include <iostream>
#include <QFile>
#include <sstream>
#include <fstream>
#include <QStringList>
#include <QString>
#include <QTextStream>
#include <QCoreApplication>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QLineEdit>
Address::Address(){}
void Address::setLines(QString ad, QString sep){
QStringList lines;
lines = ad.split(sep, QString::SkipEmptyParts);
}
QString Address::getPostalCode() const{
QStringList lines;
return lines.last();
}
QString Address::toString(QString sep) const{
QStringList lines;
return lines.join(sep);
}
bool Address::isPostalCode(QString pc){
if (pc >= "0" && pc <= "9999")
return true;
else
return false;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
while(true)
{
QString userInput = QInputDialog::getText(0,"Address Input","Please
enter your address:");
QLineEdit::EchoMode ok = QLineEdit::Normal;
QString();
if(ok && !userInput.isEmpty())
{
Address ad;
QMessageBox::information(0, "User Address",ad.toString(userInput));
}
}
return 0;
}
I got the same error. Basically, there's an issue with your compiler MingW and qMake. The best suggestion I have is to uninstall QTcreator and everything that references it. And re-install it using the new version: https://www.qt.io/download
This will install everything you need and all the right directories. Hope this helps.

Error when calling qExec "no known conversion for argument 1 to QObject"

I'm trying to create tests for a c++ application with QtTest. The three relevent files that I have are: GuiTests.cpp which contains my main function, testsuite1.cpp which contains my tests and testsuite1.h which contains the definitions of my tests. I created these files with help from different guides, for example this one.
When I try to build I get this error:
no matching function for call to 'qExec(TestSuite1 (*)(), int&, char**&)'
no known conversion for argument 1 from 'TestSuite1 (*)()' to 'QObject*'
I don't understand why, as you can see in testsuite.h below TestSuite1 is a QObject. The funny thing is this exact code (I am pretty sure) worked before but then I fiddled around with passing argc and argv to guiTest() for a while, and after I removed argc and argv and went back to what I had before (what I currently have, please see the files below) I got this error.
I've been trying to solve this problem for a long time and I can't find any answers online, so please help me, any help is appreciated. Thanks!
GuiTests.cpp
#include "testsuite1.h"
#include <QtTest>
#include <QCoreApplication>
int main(int argc, char** argv) {
TestSuite1 testSuite1();
return QTest::qExec(&testSuite1, argc, argv);
}
testsuite1.h
#ifndef TESTSUIT1_H
#define TESTSUIT1_H
#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QtTest>
class TestSuite1 : public QObject {
Q_OBJECT
public:
TestSuite1();
~TestSuite1();
private slots:
// functions executed by QtTest before and after test suite
void initTestCase();
void cleanupTestCase();
// functions executed by QtTest before and after each test
//void init();
//void cleanup();
// test functions
void testSomething();
void guiTest();
};
#endif // TESTSUIT1_H
testsuite1.cpp
#include "testsuite1.h"
#include <QtWidgets>
#include <QtCore>
#include <QtTest>
TestSuite1::TestSuite1()
{
}
TestSuite1::~TestSuite1()
{
}
void TestSuite1::initTestCase()
{
}
void TestSuite1::cleanupTestCase()
{
}
void TestSuite1::guiTest()
{
QVERIFY(1+1 == 2);
}
void TestSuite1::testSomething()
{
QLineEdit lineEdit;
QTest::keyClicks(&lineEdit, "hello world");
QCOMPARE(lineEdit.text(), QString("hello world"));
//QVERIFY(1+1 == 2);
}
//QTEST_MAIN(TestSuite1)
//#include "TestSuite1.moc"
TestSuite1 testSuite1();
declares a function named testSuite1 returning TestSuite1. Taking address of it gives you TestSuite1 (*)() (a function pointer) instead of TestSuite1* that would convert to QObject*.
Use one of the following:
TestSuite1 testSuite1;
TestSuite1 testSuite1{};
auto testSuite1 = TestSuite();
auto testSuite1 = TestSuite{};
to declare a variable.

Access Struct Object Variable within Class - C++

I'll try and explain this the best I can...
Basically, I'm writing this program for a GBA game and I'm trying to change a member variable of a struct instance from within a class. This is the code, omitting unnecessary parts:
player.cpp
#include "player.h" // Line 1
#include "BgLayerSettings.h"
player::player(){
x = 16;
y = 16;
health = 5;
direction = LEFT;
dead = false;
}
player::~player(){
}
// Omitted unrelated code
void player::ScrollScreen(){ // Line 99
if(x>((240/2)-8)){
BACKGROUND_2.h_offset += x-((240/2)-8);
}
}
player.h
#include <stdint.h> // Line 1
#include <stdlib.h>
#include <string.h>
#include "gba.h"
#include "font.h"
#pragma once
class player {
public:
player();
~player();
unsigned int x;
unsigned int y;
void ScrollScreen();
};
BgLayerSettings.cpp
#include "player.h" // Line 1
#include "BgLayerSettings"
BgLayerSettings::BgLayerSettings(){
charblock = 0;
screenblock = BLANK;
v_offset = 0;
h_offset = 0;
}
BgLayerSettings::~BgLayerSettings(){
}
BgLayerSettings.h
#include <stdint.h> // Line 1
#include <stdlib.h>
#include <string.h>
#include "gbs.h"
#include "font.h"
#pragma once
enum BACKGROUND {bg0=0, bg1, bg2, bg3, bg4, bg5, bg6, bg7,
bg8, bg9, bg10, bg11, bg12, bg13, bg14, bg15,
bg16, bg17, bg18, bg19, bg20, bg21, bg22, bg23,
bg24, bg25, bg26, bg27, bg28, DUNGEON_1, DUNGEON_FLOOR, BLANK,
};
struct BgLayerSettings {
public:
BgLayerSettings();
~BgLayerSettings();
unsigned int charblock;
BACKGROUND screenblock;
int v_offset;
int h_offset;
};
main.cpp
#include "player.h" // Line 1
#include "BgLayerSettings.h"
player Player;
BgLayerSettings BACKGROUND_0;
BgLayerSettings BACKGROUND_1;
BgLayerSettings BACKGROUND_2;
BgLayerSettings BACKGROUND_3;
// Omitted unrelated code
Essentially I'm trying to change the variable h_offset of the object BACKGROUND_2 from within the player class.
When I try to compile this, I receive this error:
player.cpp: In member function 'void player::ScrollScreen()':
player.cpp:101:3: error: 'BACKGROUND_2' was not declared in this scope
make: *** [player.o] Error 1
No matter what I try, I cannot get past this error. Anyone able to shed some light on this for me?
Thanks in advance.
It doesn't look like Player.cpp, specifically this line...
BACKGROUND_2.h_offset += x-((240/2)-8);
can see the instance of BACKGROUND_2. If you are instantiating it in main.cpp then there'd be no way for Player.cpp to see that during the build. You should pass whatever background you want to change into the function as a reference and change it from the main.cpp. Something like this instead...
void player::ScrollScreen( BgLayerSettings &bg ){ // Line 99
if(x>((240/2)-8)){
bg.h_offset += x-((240/2)-8);
}
}
Your main.cpp would be something like this...
player1.ScrollScreen( BACKGROUND_2 );