C++ frågor

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

C++ frågor

Inlägg av 4kTRB »

Har så smått kommit igång med C++ och det har redan dykt upp saker jag
inte har koll på. Allt går ju bra om man kan det dock tycker jag så här långt att
C++ är en del knöligare än Java. Java är mer rakt på.

Så till frågan: Varför fungerar inte raden
printf(stringB,m); ? (just nu är den skriven som kommentar så då fungerar det så klart inte)
För det inom " " ska väl vara en sträng?

Kod: Markera allt

//============================================================================
// Name        : MyFirstC++.cpp
// Author      : 4kTRB
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include "FirstClass.h"
#include <iostream>
#include <string>
using namespace std;

int main() {
	string stringA = "\n";
	string stringB = "%.5f\n";
	double m;
	FirstClass firstClass;
	cout << stringA;
	m = (double)firstClass.howManyClasses();
	cout << stringA;
	cout << " How many Classes: ";
	printf("%.5f\n",m);
//	printf(stringB,m);
	return 0;
}
Shimonu
Inlägg: 295
Blev medlem: 21 oktober 2015, 22:44:33

Re: C++ frågor

Inlägg av Shimonu »

Printf tar väl en char-pekare och du skickar in en "string". Jag tror du kan använda något likt stringB.c_str() för att få det.

.
kodar-holger
EF Sponsor
Inlägg: 920
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: C++ frågor

Inlägg av kodar-holger »

Kompilatorn förstår inte hur den skall type-casta en std::string till en const char * vilket är vad printf har som första parameter.

Från http://www.cplusplus.com/reference/cstdio/printf/

int printf ( const char * format, ... );

Du måste alltså anropa en metod på din string som ger dig en char* tillbaka.

Kod: Markera allt

printf(printf(stringB.c_str(),m);
fungerar antagligen bättre.
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Fungerade alldeles utmärkt.
:)


Kod: Markera allt

#include "FirstClass.h"
#include <iostream>
#include <string>
using namespace std;

int main() {
	string stringA = "====================================";
	string stringB = "%.5f\n";
	double m;
	FirstClass firstClass;
	cout << stringA << endl;
	m = (double)firstClass.howManyClasses();
	cout << stringA << endl;
	cout << " How many Classes: ";
	printf("%.2f\n",m);
	cout << stringA << endl;
	printf(stringB.c_str(),m);
	cout << stringA << endl;
	return 0;
}
ger utskriften
FirstClass
====================================
howManyClasses method says: 1
====================================
How many Classes: 1.00
====================================
1.00000
====================================
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Förklaringen på c_str() är

/**
* @brief Return const pointer to null-terminated contents.
*
* This is a handle to internal data. Do not modify or dire things may
* happen.
*/
const _CharT*
c_str() const _GLIBCXX_NOEXCEPT
{ return _M_data(); }

I min ANSI-C bok förklaras printf med:

int printf(char* format, arg, arg, ....)

Formatsträngen innehåller två typer av objekt;vanliga tecken, som kopieras till utmatningsströmmen, och
omvandlingsspecifikationer, som var och en genererar omvandling och successiv utskrift av argumenten
till printf.
kodar-holger
EF Sponsor
Inlägg: 920
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: C++ frågor

Inlägg av kodar-holger »

Du kan ju prova att använda strömmar istället för printf.

Kod: Markera allt

    std::cout << "Hello, world!" << std::endl;
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Jag blandade lite printf och cout ovan.

Lekte lite med symboliska konstanter i samband med cout.

Kod: Markera allt

#include "FirstClass.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define LOOPMAX 5
#define NEWLINE '\n'
#define HTAB '\t'
int main() {
	string stringA = "====================================";
	string stringB = "%.5f\n";
	string stringC = "AAAA";
	string stringD = "BBBB";
	double m;
	FirstClass firstClass;
	cout << stringA << endl;
	m = (double)firstClass.howManyClasses();
	cout << stringA << endl;
	cout << " How many Classes: ";
	printf("%.2f\n",m);
	cout << stringA << endl;
	printf(stringB.c_str(),m);
	cout << stringA << endl;

	for(int i = 0; i <= LOOPMAX; ++i){
		cout << stringC << HTAB;
		cout << stringD << NEWLINE << stringA << NEWLINE;
	}
	return 0;
}
Resultat:
FirstClass
====================================
howManyClasses method says: 1
====================================
How many Classes: 1.00
====================================
1.00000
====================================
AAAA BBBB
====================================
AAAA BBBB
====================================
AAAA BBBB
====================================
AAAA BBBB
====================================
AAAA BBBB
====================================
AAAA BBBB
====================================
Findecanor
Inlägg: 982
Blev medlem: 2 juli 2010, 23:04:07

Re: C++ frågor

Inlägg av Findecanor »

Bra att du hittat till "stdio.h" i sista källkoden också. ;)

Observera att printf() och cout är två olika API:er. Båda kan buffra — och använda olika buffrar. Buffrad text kanske inte töms ut till stdio förrän det ska komma ut en "\n" resp. endl. Därför kan om du blandar printf() och cout, tecken komma ut i fel ordning!
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Följande kod ger olika hexadecimal-format beroende på
om det är printf eller cout. Vad beror det på?
%x och %p förstår jag.

Kod: Markera allt

#include "FirstClass.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define LOOPMAX 5
#define NEWLINE '\n'
#define HTAB '\t'
int main() {
	string stringA = "=======================================";
	string stringB = "%.5f\n";
	string stringE = "variabeln data har värdet %i";
	string stringF = "variabeln data har adressen %p";
	string stringG = "variabeln data har adressen %x";
	int data = 77;
	int* pointerToData = &data;
	string text = "Text";
	//string* pointerToString = &text;
	FirstClass firstClass;
	//firstClass.addString(pointerToString);
	printf(stringE.c_str(),data);
	cout << NEWLINE;
	printf(stringF.c_str(),&data);
	cout << NEWLINE;
	printf(stringG.c_str(),&data);
	cout << NEWLINE << stringA << endl;
	cout << data << NEWLINE;
	cout << &data;
	cout << NEWLINE << stringA << endl;
	cout << "pointerToData " << pointerToData << NEWLINE;
	cout << "data at pointer location " << *pointerToData;

	return 0;
}
Utdata
FirstClass
variabeln data har värdet 77
variabeln data har adressen 0063FE88
variabeln data har adressen 63fe88
=======================================
77
0x63fe88
=======================================
pointerToData 0x63fe88
data at pointer location 77
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Sedan försöker jag lägga in en metod där jag kan addera en sträng till
en redan deklarerad sträng, "Text" i det här fallet.

I .h filen så säger editorn att string inte kan bli "resolved" trots att jag har #include <string> med.

Jag tycker det ser ok ut men tydligen inte?

Kod: Markera allt

//============================================================================
// Name        : MyFirstC++.cpp
// Author      : 4kTRB
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include "FirstClass.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define LOOPMAX 5
#define NEWLINE '\n'
#define HTAB '\t'
int main() {
	string stringA = "=======================================";
	string text = "Text";
	string* pointerToString = &text;
	FirstClass firstClass;
	firstClass.addString(pointerToString);


	return 0;
}

Kod: Markera allt

/*
 * FirstClass.cpp
 *
 *  Created on: 2 feb. 2019
 *      Author: 4kTRB
 */


#include <string>
#include "FirstClass.h"

FirstClass::FirstClass() {
	printf(" FirstClass \n");
	classProperty = 1;
}

int FirstClass::howManyClasses(){
	printf(" howManyClasses method says: ");
	printf("%i\n",classProperty);
	return classProperty;
}

void FirstClass::addString(string* s){
	*s += "=)";
}

Kod: Markera allt

/*
 * FirstClass.h
 *
 *  Created on: 2 feb. 2019
 *      Author: 4kTRB
 */
#ifndef _FIRSTCLASS
#define _FIRSTCLASS
#include <string>

class FirstClass {

public:
	FirstClass();
	int howManyClasses();
	void addString(string* s);

private:
	int classProperty;
};

#endif
Sado
Inlägg: 84
Blev medlem: 6 april 2007, 14:39:33
Ort: Svealand

Re: C++ frågor

Inlägg av Sado »

Möjligen för att du inte har deklarerat namespace där.
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

Det ska jag testa.

Jag provade motsvarande kod fast med en int och det fungerar bra.

Kod: Markera allt

//============================================================================
// Name        : MyFirstC++.cpp
// Author      : 4kTRB
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include "FirstClass.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define LOOPMAX 5
#define NEWLINE '\n'
#define HTAB '\t'
int main() {
	string stringA = "=======================================";
	int data = 10;
	int* pointerToData = &data;

	FirstClass firstClass;
	for(int i=0;i<LOOPMAX;i++){
		cout << stringA  << NEWLINE;
		cout << data << NEWLINE;
		firstClass.addInt(pointerToData);
	}
	cout << stringA;
	return 0;
}
/*
 * FirstClass.cpp
 *
 *  Created on: 2 feb. 2019
 *      Author: 4kTRB
 */

#include "FirstClass.h"
#include <stdio.h>

FirstClass::FirstClass() {
	printf(" FirstClass \n");
}
void FirstClass::addInt(int* a){
	*a += 10;
}
/*
 * FirstClass.h
 *
 *  Created on: 2 feb. 2019
 *      Author: 4kTRB
 */
#ifndef _FIRSTCLASS
#define _FIRSTCLASS

class FirstClass {
public:
	FirstClass();
	void addInt(int*);
};

#endif
FirstClass
=======================================
10
=======================================
20
=======================================
30
=======================================
40
=======================================
50
=======================================
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: C++ frågor

Inlägg av Icecap »

printf("%h", 0x1ABCD); ger 1abcd.
printf("%H", 0x1ABCD); ger 1ABCD.
Användarvisningsbild
4kTRB
Inlägg: 18363
Blev medlem: 16 augusti 2009, 19:04:48

Re: C++ frågor

Inlägg av 4kTRB »

namespace greppar jag inte riktigt ännu men det fungerade bra med det tipset!

Kod: Markera allt

#include "FirstClass.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define LOOPMAX 5
#define NEWLINE '\n'
#define HTAB '\t'
int main() {
	string stringA = "=======================================";
	int data = 10;
	int* pointerToData = &data;
	string text = "Skepp o Hoj";
	string* pointerToText = &text;

	FirstClass firstClass;
	for(int i=0;i<LOOPMAX;i++){
		cout << stringA  << NEWLINE;
		cout << data << NEWLINE;
		firstClass.addInt(pointerToData);
	}

	for(int i=0;i<LOOPMAX;i++){
			cout << stringA  << NEWLINE;
			cout << text << NEWLINE;
			firstClass.addString(pointerToText);
		}
		cout << stringA;

	return 0;
}
#include "FirstClass.h"
#include <stdio.h>

FirstClass::FirstClass() {
	printf(" FirstClass \n");
}
void FirstClass::addInt(int* a){
	*a += 10;
}
void FirstClass::addString(string* s){
	*s += " =)";
}
#ifndef _FIRSTCLASS
#define _FIRSTCLASS
#include <string>
using namespace std;

class FirstClass {
public:
	FirstClass();
	void addInt(int*);
	void addString(string*);
};

#endif
FirstClass
=======================================
10
=======================================
20
=======================================
30
=======================================
40
=======================================
50
=======================================
Skepp o Hoj
=======================================
Skepp o Hoj =)
=======================================
Skepp o Hoj =) =)
=======================================
Skepp o Hoj =) =) =)
=======================================
Skepp o Hoj =) =) =) =)
=======================================
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: C++ frågor

Inlägg av Mr Andersson »

Namespaces är ett sätt att organisera koden. Du kan tänka dig att de fungerar ungefär som mappar i ett filsystem.
string (och alla andra standardsaker) finns i std. Men du skulle också kunna göra en egen string-klass och lägga den i ett annat namespace för att namnen inte ska krocka.
using namespace std betyder att kompilatorn ska söka i std om den inte hittar namnet i globala namnrymden.

Sen kan det diskuteras om man ska använda using namespace i header-filer. Det anses vara lite dålig stil då du tvingar alla som inkluderar headern att importera hela std vilket inte alltid är önskvärt.

Alternativet till
using namespace std;
string s;

är
std::string s;
Skriv svar