Procházení argumentů argv – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Procházení argumentů argv – C / C++ – Fórum – Programujte.comProcházení argumentů argv – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
oxidián0
Věrný člen
10. 6. 2016   #1
-
0
-
Nahlásit jako SPAM
IP: 78.45.87.–
Reklama
Reklama
ondrej39+1
Věrný člen
10. 6. 2016   #2
-
0
-

Ta dvojtečka značí tzv. range-base cyklus, který byl do C++ doplněn až ve standardu C++11 (novější verze ho pak podporují také). Dle specifikace MSDN Visual Studio 2010 range-based cykly nepodporuje, nejjednodušší řešení je přepsat to na for cyklus klasický, jiné řešení je aktualizovat Visual Studio na novější verzi.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
KIIV+42
God of flame
10. 6. 2016   #3
-
+1
-
Zajímavé

Nebo si klidne muzes udelat vector stringu, inicializovat ho pomoci argv/argc:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

int main(int argc, char ** argv)
{
    // tento radek:
    std::vector<std::string> args(argv, argv+argc);

    // tady je jen vypis, jestli jsou tam vsechny parametry:
    std::copy(args.begin(), args.end(), std::ostream_iterator<std::string>(std::cout,"\n"));
}

EDIT: A ted koukam, ze je to tam hned jako druhe nejlepsi reseni :D

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
10. 6. 2016   #4
-
0
-

Add 1)

argv_range::
   argv_range(int argc, const char * const argv[])
        : argc_(argc), argv_(argv)
   {
   }


Nechápu jakto že není specifikovaný návratový typ, nechápu tedy co to vrací nebo co to dělá.

Add 2)

Jestli je to takhle krátké tak by to bylo super. Ale ještě jsem to nestudoval, až vyřeším jeden problém...

Jak předělat 1)? To jako musím přepsat tu funkci nebo jen tu smyčku?

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
10. 6. 2016   #5
-
0
-

argv_range je konstruktor, ten nic nevraci, jelikoz se vola pri vytvareni objektu.

Kazdopadne je ten objekt vesmes zbytecny, kdyz nemuzes pouzit range based for, coz bez standardu c++11 nemuzes.

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
10. 6. 2016   #6
-
0
-

Jo a ještě naparsovat bych je potřeboval:

test.exe randoPosition=1 randomColor=1 y=50 fontFace=6 scale=1.0

abych je mohl předat do funkce jako bool, bool, int int int double

poradíš?

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #7
-
0
-

Tak to mám a jak teď rozparsovat ty argumenty, abych je mohl rozdělit podle typu který představují?

  int i = 0;
  for (std::vector<std::string>::iterator it = args.begin(); it != args.end(); it++)
     {
        std::cout << "args[" << i << "] = " << args[i] << std::endl;
        i++;
    }  

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
10. 6. 2016   #8
-
0
-

#7 oxidián
Budeš si muset udělat parser, jiná možnost není. Parser bude obsahovat nejspíše if/else bloky, kde na základě obsahu zrovna zkoumaného řetězce (který dostaneš z proměnné argv) budeš muset řetězec rozdělit pomocí znaku '=' a pravou stranu po rozdělení přetypovat na žádaný formát (čísla je možné ze stringu získat například metodami jako je atoi nebo atof - jsou pak modernější verze stoi, stod, atd., které umějí pracovat přímo s std::string, ale nevím, od jaké verze C++ v jazyce jsou).

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Věrný člen
10. 6. 2016   #9
-
0
-

Jaký použít kontejner

vector<vector<std::string> > arguments;

asi nebude to pravé ořechové vektory se prochází po jedné a já potřebuju přistupovat

kontejner[argument] ... vrátí std::string "value";

např

kontejner["soubor"] ... vrátí std::string "lena.jpg";

jinak vektor bych asi taky použít mohl když bych použil něco jako vector<OBJEKT_TYP> kde OBJEKT_TYP by byl pár argument, value, ale to by bylo moc složité na přistupování a zjišťování která položka obsahuje hledaný argument.

Edit:

Našel jsem:

std::map<std::string,std::string> arguments;

Nahlásit jako SPAM
IP: 78.45.87.–
hlucheucho+10
Posthunter
10. 6. 2016   #10
-
0
-

vector se používá i jako pole, má přetížený operátor [], co si přečíst dokumentaci nebo nějaký tutoriál? Ony ty argumenty nejsou nic jiného než pole.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
oxidián0
Věrný člen
10. 6. 2016   #11
-
0
-

Na to teď není čas.

Mám toto:

#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>

class wrapper {
	public:
		std::map<std::string,std::string> arguments;
		wrapper(int argc, char ** argv);
	private:
		int argc; char ** argv;
		std::vector<std::string> args;
};
#include "wrapper.h"

wrapper::wrapper(int argc, char ** argv):argc(argc),argv(argv)
  {
  std::vector<std::string> this->args(argv, argv+argc);
  this->args;
  // this->arguments;
  int i = -1;
  for (std::vector<std::string>::iterator it = this->args.begin(); it != this->args.end(); it++)
 	{
		i++;
		std::cout << "args[" << i << "] = " << this->args[i] << std::endl;
		int o = (int) this->args[i].std::string::compare(0,14,"randomPosition");
		int r = (int) this->args[i].std::string::compare(0,11,"randomPosition");
		if ( this->args[i].std::string::compare(0,14,"randomPosition") == 0) {
			this->arguments.insert(std::make_pair(args[i].substr (0,14),args[i].substr (16,this->args[i].length()-1 )));
		}
		else if ( args[i].std::string::compare(0,11,"randomColor") == 0) {
			  this->arguments.insert(std::make_pair(args[i].substr (0,11),args[i].substr (13,this->args[i].length()-1 )));
		}
	}  
  };

Nevím však jak mám vyřešit ten řádek


std::vector<std::string> this->args(argv, argv+argc);
původně


std::vector<std::string> args(argv, argv+argc);

v deklaraci nedávám (argv, argv+argc).
to patří přece do implementační části.

Nahlásit jako SPAM
IP: 78.45.87.–
vitamin+8
Grafoman
10. 6. 2016   #12
-
0
-

#11 oxidián
 

wrapper::wrapper(int argc, char ** argv):
argc(argc),
argv(argv),
args(argv, argv+argc){
  ///...
}

 

///toto ti funguje?
int o = (int) this->args[i].std::string::compare(0,14,"randomPosition");
Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV+42
God of flame
10. 6. 2016   #13
-
0
-

Nasel jsem treba libku http://tclap.sourceforge.net/ tak by se treba dala pouzit ta.

Vypada, ze staci jen mit ten adresar include, nic jineho tam potreba neni.

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
10. 6. 2016   #14
-
0
-

#11 oxidián
Nechápu, proč se snažíš dělat všechno na jednou. Je úplně normální, že se aplikace skládají z menších bloků z nichž děláš bloky složitější.

Udělej to následujícím postupem:

  1. Vezmi hodnoty proměnných argc a argv.
  2. Index 0 v poli argv můžeš ignorovat, protože obsahuje název programu.
  3. Argumenty začínající 1. indexem a končící indexem (argc - 1) rozparsuj podle znaménka '=', z každého argv ti tedy vznikne vector o dvou prvcích, levá strana a pravá strana, pokud budeš mít vektor jenom o jednom prvku, vyhoď výjimku, argument je neplatný.
  4. Porovnej první element výstupní vectoru z funkce, pomocí níž jsi rozdělil argument, zda se jedná o argument, který zpracováváš (například randomPosition), pokud ho zpracovat neumíš, vyhoď výjimku.
  5. Pokud jsi schopen argument zpracovat, zkus pravou stranu přetypovat na hodnotu, kterou na pravé straně očekáváš, pokud nejsi schopen pravou stranu přetypovat, vyhoď výjimku.
  6. Pokud ses dostal až sem, přiřaď výsledek do mapy, kde jako klíč použiješ název argumentu a jako jeho hodnotu přetypovaná původní řetězec na číselný datový typ.

Nutno podotknout, že možnost zadávat jako hodnoty argumentů jak celá čísla tak čísla s pohyblivou desetinnou čárkou značně ztěžují parsování a budeš to muset řešit dvěma rozdílnými bloky.

P.S. A ten řádek, co zmínil vitamin, ten ti prostě fungovat nemůže.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Věrný člen
10. 6. 2016   #15
-
0
-

#12 vitamin
fungovalo než jsem to začal přesouvat z main do třídy. dám tam metodu aby se to zjednodušilo

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #16
-
0
-

#14 ondrej39
a přece funguje. Proč?

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #17
-
0
-

   

// These 5 are used to get argv to vector
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>

#define ARGS_CAPACITY 12;

class Wrapper {
	public:
		std::map<std::string,std::string> arguments;
		Wrapper(int argc, char ** argv);
	private:
		std::string predefinedArgs[2];
		int argc; char ** argv;
		std::vector<std::string> args;
		void parseArguments();
};
#include "wrapper.h"

Wrapper::Wrapper(int argc, char ** argv):
  argc(argc),
  argv(argv),
  args(argv, argv+argc){
	  this->predefinedArgs[12] = { "Jan", "Feb", "Mar", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" };
	  this->parseArguments();
  };
void Wrapper::parseArguments()
  {
  int i = -1;
  for (std::vector<std::string>::iterator it = this->args.begin(); it != this->args.end(); it++)
 	{
		i++;
		std::cout << "args[" << i << "] = " << this->args[i] << std::endl;
		int o = (int) this->args[i].std::string::compare(0,14,"randomPosition");
		int r = (int) this->args[i].std::string::compare(0,11,"randomPosition");
		if ( this->args[i].std::string::compare(0,14,"randomPosition") == 0) {
			this->arguments.insert(std::make_pair(args[i].substr (0,14),args[i].substr (16,this->args[i].length()-1 )));
		}
		else if ( args[i].std::string::compare(0,12,"randomColor") == 0) {
			  this->arguments.insert(std::make_pair(args[i].substr (0,12),args[i].substr (13,this->args[i].length()-1 )));
		}
	}  
  };


Na řádku s implementací

this->predefinedArgs[12] = { "Jan", "Feb", "Mar", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" };

wrapper.cpp(7): error C2059: syntax error : '{'

Proč? To jsem vzal tady

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
10. 6. 2016   #18
-
0
-

#17 oxidián
moc pozde, taky ponekud divne... mas pole 2 retezcu a pak se snazis priradit do 13 pozice celou sadu retezcu....

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
10. 6. 2016   #19
-
0
-

#17 oxidián
A sada retazov mimo deklaracie premennej je povolena az od c++11 a vola sa to std::initializer_list

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
ondrej39+1
Věrný člen
10. 6. 2016   #20
-
0
-

#16 oxidián
Aha, já si až teď všimnul, že ty pořád pracuješ jenom se stringy, ale číselnou hodnotu z argumentů stále nemáš.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Věrný člen
10. 6. 2016   #21
-
0
-

#20 ondrej39
KIIV mi poradil to nakonec přetypovat. Myšlenka je jednoduchá. Jen potřebuju vytvořit 2 pole. Jedno pole se stringy levá část argumentu. Druhé pole s typy pro jednotlivé argumenty. Ani jedno nevím jak udělat. Musím to dělat dynamicky pomoci Maloka??

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #22
-
0
-

A toto?

const char* MONTHS[] = { "Jan", "Feb", "Mar", "April", "May", "June", "July", 
    "Aug", "Sep", "Oct", "Nov", "Dec" };

 Takto?

const char* predefinedArgs;
this->predefinedArgs = { "Jan", "Feb", "Mar", "April", "May", "June", "July", 
    "Aug", "Sep", "Oct", "Nov", "Dec" };

wrapper.cpp(7): error C2059: syntax error : '{'

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
10. 6. 2016   #23
-
0
-

#21 oxidián
V příspěvku 11 ode mě máš přesně popsané, co máš udělat. Krok po kroku.

Nabízí se ještě jedno řešení, kdy budeš mít mapu key->value jako std::string (levá strana)->std::string (pravá strana) a přetypování na číselnou hodnotu provedeš teprve až když se na danou hodnotu z Wrapperu pro argumentu dotážeš. Tímto způsobem bys pak měl pouze jednu mapu a nemusel jich mít více v závislosti na počtu typů hodnot, které do argumentů můžeš přiřadit.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Věrný člen
10. 6. 2016   #24
-
0
-

#23 ondrej39
Ale já už mám svoje řešení, jen potřebuju vyřešit to pole a typy.

Nahlásit jako SPAM
IP: 78.45.87.–
hlucheucho+10
Posthunter
10. 6. 2016   #25
-
0
-

Po parsování bych se snažil držet klíč - hodnota pohromadě. Takže bych si udělal jednoduchou strukturu se dvěma položkama a tyto struktury pak ukládal do vectoru, pole.... Už jsem ti kdysi vytknul nekoncepčnost, chaotičnost. Každopádně znovu a znovu: promysli si co chceš udělat a pak jak to udělat a teprve pak kóduj.

Co ti poradil ondrej39 má hlavu a patu.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
oxidián0
Věrný člen
10. 6. 2016   #26
-
0
-

no však to v tom kontaineru map tak mám pohromadě

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #27
-
0
-

Jak vytvořit to pole už vím. Co ale nevím:

Jak přesunout predefArgs do souborů .h a .cpp moji třídy? Jak to rozdělit? Jde to nebo ne?

std::string predefArgs[] = { "Some", "Other", "Strings" };

int main(int argc, char ** argv) { return 0; }
Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
10. 6. 2016   #28
-
0
-

Už to skoro mám, ale potřebuju poradit jak vytvořit pointer odkazující na tento typ v rámci třídy Wrapper:

static const std::string predefinedArgs[12]

te´d to píše chybu error C2143: syntax error : missing ';' before '['

Co potřebuju udělat je posouvat pointer v každém cyklu o jedna nahoru:

const std::string[12] * pArgs = predefinedArgs;
for (int c=0; c<ARGS_CAPACITY;c++)
	{
	pArgs++;
	len = this->predefinedArgs.length();

teď to píše

error C2143: syntax error : missing ';' before '['

když tam nedám const ... [12] tak zase píše chybu nekompatibility typů

Nahlásit jako SPAM
IP: 78.45.87.–
vitamin+8
Grafoman
10. 6. 2016   #29
-
0
-

   

static const std::string predefinedArgs[12];
    
const std::string* pArgs = predefinedArgs;
Nahlásit jako SPAM
IP: 78.141.123.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
oxidián0
Věrný člen
11. 6. 2016   #30
-
0
-

Takže dík za spolupráci. Mám to hotové a jedete. Myslím že by se to dalo ještě zkrátit pomocí makra (switch). Teď ale stačí. Mám hotovo.

 header

// These 7 are used to get argv to vector
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>

#define ARGS_CAPACITY 12

enum ARG_TYPES {
	bool_ = 0,
	int_ = 1,
	float_ = 2,
	double_ = 3,
	string_ = 4
};
typedef struct VALUE {
	int type;
	bool bool_;
	int int_;
	float float_;
	double double_;
	std::string string_;
	} value;

class Wrapper {
	public:
		std::map<std::string,VALUE> arguments;
		Wrapper(int argc, char ** argv);
	private:
		int argc; char ** argv;
		std::vector<std::string> args;
		static const std::string predefinedArgs[12];
		static const int predefinedArgTypes[ARGS_CAPACITY];
		void parseArguments();
};

cpp

#include "wrapper.h"

/*
What is expected from arguments:
0 - bool
1 - int
2 - float
3 - double
4 (anything else) - string
*/

const std::string Wrapper::predefinedArgs[ARGS_CAPACITY] = 
	{ "randomPosition", "randomColor", "x", "y", "fontFace", "scale", "July", "Aug", "Sep", "Oct", "Nov", "Dec" };

const int Wrapper::predefinedArgTypes[ARGS_CAPACITY] = 
	{ 0,								0,						   1,	 1,		1,					2,					0, 0, 0, 0, 0, 0 }; // 0 - int ; 1 - double
Wrapper::Wrapper(int argc, char ** argv):
  argc(argc),
  argv(argv),
  args(argv, argv+argc)
  {
	std::cout << Wrapper::predefinedArgs << std::endl;
	this->parseArguments();
  };

 void Wrapper::parseArguments()
  {
  int i = -1;
  std::string s;
  bool match_procceed;
  for (std::vector<std::string>::iterator it = this->args.begin(); it != this->args.end(); it++)
 	{
	    match_procceed = false;
		i++;
		if (i == 0)
			continue;
		std::cout << "args[" << i << "] = " << this->args[i] << std::endl;
		// int o = (int) this->args[i].std::string::compare(0,14,"randomPosition");
		int r = (int) this->args[i].std::string::compare(0,11,"randomPosition");
		size_t len;
		// const std::string[12] pArgs = predefinedArgs;
		const std::string* PA_ptr = predefinedArgs;
		const std::string* pPA  = predefinedArgs;
		// Search needle:
		for (int c=0; c<ARGS_CAPACITY;c++)
			{
				pPA = (PA_ptr+c);
				len = pPA->length(); // length of "needle"
				//int lenWord = this->args[i].length();
				int o = this->args[i].std::string::compare(
					0,len,*pPA);
 				if ( this->args[i].std::string::compare(
					0,len,*pPA) == 0) 
					{
					s = this->args[i].substr (len+1,this->args[i].length());
					VALUE value;
					switch(this->predefinedArgTypes[c]){
						case bool_:
							value.bool_ = (bool) std::stoi(s);
							value.type=bool_;
							break;
						case int_:
							value.int_ = (int) std::stoi(s);
							value.type=int_;
							break;
						case float_:
							value.float_ = (float) std::stoi(s);
							value.type=float_;
							break;
						case double_:
							value.double_ = (double) std::stoi(s);
							value.type=double_;
							break;
						default:
							value.string_ = s;
							value.type=string_;
					} // end of switch

					this->arguments.insert(
							std::make_pair(
									this->args[i].substr (0,len),	 value
							));
					match_procceed = true;
					break;
					}
			} // end of inner for - searching needle
	if ( match_procceed )
					continue;
	}  // outer loop - goung through input argv data
  };

Příště zkusím použít vector.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
12. 6. 2016   #31
-
0
-

Zase to předělávám a dostal jsem se do problému. Vše jsem přesunul do třídy Arguments. Ve funkci main chci zavolat

Wrapper wrapper(argc, argv);

Teď je třeba vytvořit instanci třídy arguments pod wrapper->arguments a přitom do konstruktoru předat ty samé argumenty (argc, argv).

Mám

class Wrapper {
   public:
     Wrapper(int argc, char ** argv);
     Arguments arguments(int argc, char ** argv);
};
#endif
Wrapper::Wrapper(int argc, char ** argv)/*:
  argc(argc),
  argv(argv),
  args(argv, argv+argc)*/
  {
  };

Bude toto fungovat? Zdá se mi že to nefunguje, jak kdyby arguments neexistoval nebo neměl správně nastavené členy. Očekával bych že by do implementace konstruktoru mělo přijít něco jako Arguments arguments(argc, argv) nevím

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
12. 6. 2016   #32
-
0
-

#31 oxidián
no jestli to chapu spravne, tak se nedivim, mas tam tridni promennou arguments, ale neinicializujes ji (jen args).

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
12. 6. 2016   #33
-
0
-

args je zakomentovaný

jak iniciovat?

this->arguments (int argc, char ** argv)

nechápu

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
12. 6. 2016   #34
-
0
-

Mas nejakou spustitelnou ukazku kodu? A proc vlastne vsude cpes this->... ? Co patri k tride, tak ty parametry vidi. Arguments mas v predchozi verzi jako mapu, a ty to predas dost tezko tim zpusobem

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
12. 6. 2016   #35
-
0
-

Teď to je jinak. Co bylo ve Wrapper jsem přeunul do Arguments. Arguments je třída. Potřebuju vytvořit novou instanci třídy Arguments a to uložit pod Wrapper. Ta mapa je pod Arguments

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
12. 6. 2016   #36
-
0
-

Takze od zacatku - mas tridu Wrapper, v nem metodu: 

Arguments arguments(int argc, char ** argv);

Pak to z venku vytahujes jak? Jak je vlastne implementovana ta metoda arguments?

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
12. 6. 2016   #37
-
0
-

#36 KIIV
Ale nemám tam metodu arguments. To jsem se jen snažil deklarovat člena arguments pod který chci uložit tu třídu.

Opravuji deklaraci,

#include "arguments.hpp"

class Wrapper {
	public:
		Wrapper(int argc, char ** argv);
		Arguments arguments;
};


Není podstatné co je uvnitř třídy Arguments. Jde o to že nevím jak bytvořit novou instanci a zároveň spustit konstruktor a zároveň tu instanci uložit pod this->arguments.

dal bych do implementace konstruktoru Wrapper::Wrapper:

Arguments arguments(argc, argv);

Arguments * pArguments;

this->arguments = pArguments;

konstruktor se ukončí, instance arguments zanikne a až ji zavolám tak to celé krachne? Protože bych uložil jen pointer... Ale já chci uložit objekt pod arguments ne jen pointer.

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
12. 6. 2016   #38
-
0
-

   

Wrapper::Wrapper(int argc, char ** argv) : arguments(argc, argv)
{
}

Tohle nefunguje?

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #39
-
0
-

Ty, jo zdá se že by to mohlo fungovat. Zkompilovalo se to. Takže to co dostává konstruktor Wrapper to se sdílí jako vstup do arguments()... Jestli sem to správně pochopil. Jinak asi mám vokno a nevím už jak jsem to předtím dělal.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
13. 6. 2016   #40
-
0
-

Tak ne, nefunguje to. konstuktor arguments se nespustí. Navíc nechápu jakto že to nehodí chybu.

argc a argv už nejsou součástí třídy Wrapper. To jsem přesunul pod Arguments.

I když bych je teda vzal od constructoru Wrapper a předal do : arguments(..) tak tím se ale přece nevytváří noví instance Arguments, to by se mi musel kód zastavit v konstruktoru Arguments.

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #41
-
0
-

#40 oxidián
Tady je ukazka, ze to funguje:  (parametry musi byt ve tvaru  --param=value  a nepodporuje vicenasobne hodnoty (to by tam musela byt multimapa), nepodporuje ani typy, preddefinovane parametry a tak. Jen trivialni implementace

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

typedef const std::vector<std::string>       arguments_t;
typedef std::map<std::string, std::string>      values_t;

class Arguments {
  public:
    Arguments (arguments_t & args);

    values_t                                      values;
};

Arguments::Arguments(arguments_t & args) {
    std::cout << __func__ <<  ": konstruktor!\n";
    for (arguments_t::const_iterator i = args.begin(); i != args.end(); ++i) {
        if (i->substr(0,2) == "--") {
            size_t pos = i->find("=");
            if (pos != std::string::npos) { 
                values.insert(std::make_pair(i->substr(2,pos-2), i->substr(pos+1)));
            }
        }
    }
}

class Wrapper {
  public:
    Wrapper (int, char **);

    Arguments                                 arguments;
};

Wrapper::Wrapper (int argc, char ** argv) :
   arguments(arguments_t(argv+1, argv+argc))
{
    std::cout << __func__ <<  ": konstruktor!\n";
}

int main(int argc, char ** argv)
{
    Wrapper w (argc, argv);

    for (values_t::iterator i = w.arguments.values.begin(); i != w.arguments.values.end(); ++i) {
        std::cout << "'" << i->first << "' = '" << i->second << "'\n";
    }
}

Jinak argv a argc potrebujes jen jako parametry, nemusis to cpat primo do tridy, nemusis je znat po zpracovani.

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #42
-
0
-

Jenže ty to máš úplně jinak použil si typedef a to já nedělal. navíc tam stále pracuješ s kontejnerem, což pro zjednodušení není třeba. Podívám se na to ještě později. Teď musím končit

A Arguments() nemá přijímat kontejner, ale argv a argc stejně jako Wrapper

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #43
-
0
-

typedef je tam jen pro zjednoduseni - nemusim pak vsude psat
std::map<std::string, std::string>

a

std::map<std::string, std::string>::iterator

a tak dale...

Kazdopadne konstruktor funguje, pokud ne, tak mas nejakou pitomost v kodu, jenze aktualni kod neznam, tak netusim jakou.
 

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #44
-
0
-

arguements.h  

/** Define your CLI arguments **/

#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>

#define ARGS_CAPACITY 8

enum ARG_TYPES {
	bool_ = 0,
	int_ = 1,
	float_ = 2,
	double_ = 3,
	string_ = 4
};
typedef struct VALUE {
	int type;
	bool bool_;
	int int_;
	float float_;
	double double_;
	std::string string_;
	} value;

class Arguments{
	public:
		Arguments(int argc, char ** argv);
		bool useHarrisDetector;
		int maxCorners, maxTrackbar, minDistance, blockSize;
		double qualityLevel,k;
		std::string file, subimage, text;

		std::map<std::string,VALUE> arguments_container;
		void getArguments();
		static std::string predefinedArgs[ARGS_CAPACITY];
		static int predefinedArgTypes[ARGS_CAPACITY];

private:
		int argc; char ** argv;
		std::vector<std::string> args;
		void Arguments::parseArguments();
};


cpp

#include "arguments.hpp"

/*
What is expected from arguments:
0 - bool
1 - int
2 - float
3 - double
4 (anything else) - string
*/

std::string Arguments::predefinedArgs[ARGS_CAPACITY] = 
	{ "file", "maxCorners", "maxTrackbar", "qualityLevel", "minDistance", "blockSize", "useHarrisDetector", "k" };
int Arguments::predefinedArgTypes[ARGS_CAPACITY] = 
	{ 4,			1,						   1,							3,							1,							1,					0,									3};

// Set default values here:
Arguments::Arguments(int argc, char ** argv):
	// Initiate default arguments
	file("../../data/lena.jpg"),
	maxCorners(100),
	maxTrackbar(100),
	qualityLevel(0.01),
	minDistance(10),
	blockSize(3),
	useHarrisDetector(false),
    k(0.04)
	{
	std::cout << Arguments::predefinedArgs << std::endl;
	this->parseArguments();
	this->getArguments();	
	};

void Arguments::parseArguments()
  {
  int i = -1;
  std::string s;
  bool match_procceed;
  for (std::vector<std::string>::iterator it = this->args.begin(); it != this->args.end(); it++)
 	{
	    match_procceed = false;
		i++;
		if (i == 0)
			continue;
		std::cout << "args[" << i << "] = " << this->args[i] << std::endl;
		// int o = (int) this->args[i].std::string::compare(0,14,"randomPosition");
		int r = (int) this->args[i].std::string::compare(0,11,"randomPosition");
		size_t len;
		// const std::string[12] pArgs = predefinedArgs;
		const std::string* PA_ptr = predefinedArgs;
		const std::string* pPA  = predefinedArgs;
		// Search needle:
		for (int c=0; c<ARGS_CAPACITY;c++)
			{
				pPA = (PA_ptr+c);
				len = pPA->length(); // length of "needle"
				//int lenWord = this->args[i].length();
				int o = this->args[i].std::string::compare(
					0,len,*pPA);
 				if ( this->args[i].std::string::compare(
					0,len,*pPA) == 0) 
					{
					s = this->args[i].substr (len+1,this->args[i].length());
					VALUE value;
					switch(this->predefinedArgTypes[c]){
						case bool_:
							value.bool_ = (bool) std::stoi(s);
							value.type=bool_;
							break;
						case int_:
							value.int_ = (int) std::stoi(s);
							value.type=int_;
							break;
						case float_:
							value.float_ = (float) std::stoi(s);
							value.type=float_;
							break;
						case double_:
							value.double_ = (double) std::stoi(s);
							value.type=double_;
							break;
						default:
							value.string_ = s;
							value.type=string_;
					} // end of switch

					this->arguments_container.insert(
							std::make_pair(
									this->args[i].substr (0,len),	 value
							));
					match_procceed = true;
					break;
					}
			} // end of inner for - searching needle
	if ( match_procceed )
					continue;
	}  // outer loop - goung through input argv data
  };

void Arguments::getArguments(){
	// Load defaults
	int i =-1;
	for (std::map<std::string,VALUE>::iterator it = this->arguments_container.begin(); it != this->arguments_container.end(); it++)
		{
		int len = (it->first).length();
		switch(it->second.type){
			case bool_:
				if ( it->first.std::string::compare(
					0,len,"useHarrisDetector") == 0)
					{ this->useHarrisDetector = it->second.bool_;break;}
				break;
			case int_:
				if ( it->first.std::string::compare(
					0,len,"maxCorners") == 0)
					{ this->maxCorners = it->second.int_;break;}
				else if ( it->first.std::string::compare(
					0,len,"maxTrackbar") == 0)
					{ this->maxTrackbar = it->second.int_;break;}
				else if ( it->first.std::string::compare(
					0,len,"minDistance") == 0)
					{ this->minDistance = it->second.int_;break;}
				else if ( it->first.std::string::compare(
					0,len,"qualityLevel") == 0)
					{ this->qualityLevel = it->second.int_;break;}
				else if ( it->first.std::string::compare(
					0,len,"blockSize") == 0)
					{ this->blockSize = it->second.int_;break;}
				break;
			case double_:
				if ( it->first.std::string::compare(
					0,len,"qualityLevel") == 0)
					{ this->qualityLevel = it->second.double_;break;}
				else if ( it->first.std::string::compare(
					0,len,"k") == 0)
					{ this->k = it->second.double_;break;}
				break;
			case string_:
				if ( it->first.std::string::compare(
					0,len,"file") == 0)
					{ this->file = it->second.string_;break;}
				break;
			}
		} // for
 }

wrapper.hj

// These 7 are used to get argv to vector
#ifndef WRAPPER_H
#define WRAPPER_H

#include "arguments.hpp"

class Wrapper {
	public:
		Wrapper(int , char ** );
		Arguments arguments;
};
#endif

cpp

#include "wrapper.hpp"

Wrapper::Wrapper(int argc, char ** argv):
  /*  
  argc(argc),
  argv(argv),
  args(argv, argv+argc)*/
  arguments(argc, argv)
  {
  
  };
Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #45
-
0
-

Takze zatim prvni co me nezbytne prastilo do oci je pouzivani args, nicmene zadnej explicitni konstruktor. Coz priblizne znamena, zadne data k parsovani.

Pak argv a argc si vubec nemusis ukladat. Staci mit v konstruktoru Arguments taky inicializaci konstruktoru :args(argv+1, argv+argc) -  a ted koukam, ze si argv a argc ani neukladas v ramci tridy...

Furt tam cpes  this->  ikdyz ty tridni parametry jsou proste ve tride videt. (kdo vi, jestli dereference pointeru a tak nebude ve finale pomalejsi)

V arguments.h mas pak  void Arguments::parseArguments(); - zvyraznena cast tam byt nema.

std::cout << Arguments::predefinedArgs << std::endl; tiskne jen pointer toho predefinedArgs, ne jeho obsah!!!

Jeste jedna vec: na co tam ten wrapper vubec mas?

A tak dale

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
13. 6. 2016   #46
-
0
-

#44 oxidián
Dalsi WTF - proc v parseArguments prochazis pomoci iteratoru, ktery nepouzijes a pak jeste pocitas indexy?

+ Kdyz hodnotu ++ opravdu nepotrebujes, VZDY pouzij preinkrementaci. Post inkrementace muze byt velice draha hlavne u objektu, protoze se vytvari novy objekt.

EDIT: koukam, ze by to chtelo asi spis doplnit dotazy v kodu, tohle je fakt o posilani WTF ke kazdemu radku :)

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
13. 6. 2016   #47
-
0
-

Ostatne ja bych to resil spis nejak takto:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <map>

class Arguments {
  public:
    class ParamBase {
      public:
        virtual bool parse(std::string const & v) = 0;
        virtual ~ParamBase() {}
    };

    template <class TYPE>
    class Param : public ParamBase {
      public:
        Param(TYPE & ref) : m_ref(ref) {}
        virtual ~Param() {}
        virtual bool parse(std::string const & v) {
            std::istringstream str(v);
            return (bool)(str >> m_ref);
        }
      protected:
        TYPE &         m_ref;
    };

    template <class TYPE>
    bool addParam(std::string const & name, TYPE & ref) {
        return m_arguments.insert(std::make_pair(name, new Param<TYPE>(ref))).second;
    }

    bool parse(std::string const & str) {
        size_t pos = str.find("=");
        if (pos != std::string::npos) {
            std::map<std::string, ParamBase *>::iterator it = m_arguments.find(str.substr(0,pos));
            if (it != m_arguments.end()) {
                it->second->parse(str.substr(pos+1));
            }
        }
    }

    ~Arguments() {
        std::map<std::string, ParamBase *>::iterator it = m_arguments.begin();
        while (it != m_arguments.end()) {
            delete it->second;
            ++it;
        }
        m_arguments.clear();
    }

    std::map<std::string, ParamBase *>    m_arguments;
};

class Configuration {
  public:
    Configuration(char ** begin, char ** end)
    : param1(0)
    , param3(false)
    , param4(0.024)
    {
        m_argumentParser.addParam("--param1", param1);
        m_argumentParser.addParam("--param2", param2);
        m_argumentParser.addParam("--param3", param3);
        m_argumentParser.addParam("--param4", param4);

        for ( ; begin != end; ++begin) {
            m_argumentParser.parse(*begin);
        }
    }
    
    int                   param1;
    std::string           param2;
    bool                  param3;
    double                param4;
  protected:
    Arguments   m_argumentParser;
};

int main(int argc, char ** argv) {
    Configuration cfg = Configuration(argv+1, argv+argc);

    std::cout << "param1: " << cfg.param1 << "  param2: " << cfg.param2 << "  param3: " << cfg.param3 << "  param4: " << cfg.param4  << "\n"; 
}

Akorat pro std::string by se asi musela udelat specializace, aby to nepouzilo string stream ale rovnou zkopirovalo cely retezec... (ted to vezme jen jedno slovo)

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #48
-
0
-

Je toho moc co si napsal a já se v první řadě musím vyjádřit hned k tvé první větě:

Takze zatim prvni co me nezbytne prastilo do oci je pouzivani args, nicmene zadnej explicitni konstruktor.

 Však to je to na co se tě od včera ptám, jak udělat ten konstruktor. V arguments.h je toto 

int argc; char ** argv;

std::vector<std::string> args;

potřebuju tedy data z Wrapper::Wrapper(int argc; char ** argv) dostat do toho konstruktoru Arguments::Arguments, ale nevím jak to mám udělat. Kdyby šlo o založení nové instance do proměnné arguments tak udělám jen

Arguments arguments(int argc; char ** argv)

ale já nemám proměnnou, nýbrž člena třídy a v tomto případě si numím poradit.

Snažit se o něco jako Arguments $this->arguments(int argc; char ** argv)

by určitě nefungovalo.

Jeste jedna vec: na co tam ten wrapper vubec mas?

Příjde mi dobrý nápad sdružovat podstatné části kódu do wrapperu, pak do metod jiných tříd stačí zadat wrapper jako první argument a dostanu se tak k dalším uloženým věcem jako třeba k argumentům. Tohle je malý program, který by wrapper nepotřeboval, ale chci všechno balit obecně ne jen tady.

i používám ke zpřístupnění args, i když je to vector tak snad zbytečné.

Tvůj kód je na mě moc složitý. Potřebuju vyřešit ten konstruktor a nevím jak. Zatím vše

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #49
-
0
-

#48 oxidián
 

Arguments::Arguments(int argc, char ** argv):
	// Initiate default arguments
	file("../../data/lena.jpg"),
	maxCorners(100),
	maxTrackbar(100),
	qualityLevel(0.01),
	minDistance(10),
	blockSize(3),
	useHarrisDetector(false),
	k(0.04),
        args(argv+1, argv+argc) // rovnou preskocime prvni prvek, coz je nazev programu
	{
	std::cout << Arguments::predefinedArgs << std::endl;
	this->parseArguments();
	this->getArguments();	
	};

A  ve Wrapper::Wrapper(... je to dobre...

EDIT: o tom, jak ten konstruktor volat jsem uz psal vcera, takze jen pro jistotu ke kodu o par radku nahoru -  tento radek (pod "k(0.04),") je KONSTRUKTOR:

args(argv+1, argv+argc)
Vic explicitne uz to proste napsat nedokazu

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #50
-
0
-

#49 KIIV

args(argv+1, argv+argc)

Tos psal včera? To si nepamatuju. Co znamená to +1 a +argc? Proč si to tam dal?

Teď když se zpětně dívám do původního kódu (ne ten co probíráme teď) tak tam mám deklaraci

Wrapper(int argc, char ** argv);

std::vector<std::string> args;

... A implementaci Wrapper::Wrapper(int argc, char ** argv):argc(argc),argv(argv),args(argv, argv+argc) to si psal ty 10.6. a já to opsal aniž bych věděl proč je tam ten součet. Tak to je vstup do toho kontejneru. takže + je speciální operátor který používá ten vector? Ještě se dívám na dokumentaci která syntaxe to asi je, když používáš dva argumenty... žádná syntaxe mi k tvému příkladu nesedí.

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #51
-
0
-

std::vector ma jeden z konstruktoru inicializaci pomoci dvou iteratoru (ale jde pouzit i poitery - toho tu vyuzivam) - ukazatel na prvni prvek (tj, argv) a ukazatel za posledni prvek (tj, argv+argc). Jelikoz prvni prvek argv je nazev programu a stezi v nem bude neco zajimaveho (a stejne to pak v cyklu preskakujes), tak jsem ho vynechal pomoci +1.

Vcera jsem uz nekolikrat zminoval:

Wrapper::Wrapper(int argc, char ** argv) : arguments(argc, argv) { }

To same funguje pro vsechny tridni promenne typu vector<string> args.
No a kdyz tolik pouzivas : konstruktor_tridni_promenne(1), .... tak jsem myslel, ze vis co delas (a proc) :D

Jo a ve tretim prispevku: http://programujte.com/forum/vlakno/31136-prochazeni-argumentu-argv/#p211317 je to same, jen ne uvnitr tridy. A s tim nazvem programu.

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 6. 2016   #52
-
0
-

To je ten příspěvek o kterém jsem psal. No to já právě jen opsal od tebe.

Takže myslíš nejspíš tento konstruktor:


(3) range constructor

template <class InputIterator> vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());

Constructs a container with as many elements as the range [first,last), with each element constructed from its corresponding element in that range, in the same order.

Přičemž "template <class InputIterator>" chápu jako typ std::vector<std::string> ve kterém je člen args.

Konečně to chápu. Tedy jestli jsem to pochopil správně, pole se dá použít místo iterátoru. Kdybys tam dal (argv,argv) tak by se do kontejneru měl uložit jen název programu?

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
13. 6. 2016   #53
-
0
-

#52 oxidián
pokud pouzijes  (argv, argv) tak to nevlozi nic, ten last tam nepatri - to je naznaceno tim intervalem: [first, last)

Obecne .end() iterator odkazuje ZA posledni prvek. Proto jsem daval  argv+argc - kdyz bych udelal neco s argv[argc], tak uz ukazuju na neplatne data (za pole).

A funguje to proto, ze je to template. Musi to jen byt schopne udelat ++iterator a  *iterator - coz u pointeru jde.

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
14. 6. 2016   #54
-
0
-

Udělal jsem si poznámky takže tohle bych už zapomenout neměl. Dík za vysvětlení a za trpělivost

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
17. 6. 2016   #55
-
0
-

Jak si to myslel s tím vypuštěním proměnné i?

Takhle to nefunguje:

int r = (int) it.std::string::compare(0,11,"randomPosition");

this->args[i] nahradit přímo it je k ničemu

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #56
-
0
-

#55 oxidián
it je iterator (obdoba pointeru). Coz znamena, ze ho musis dereferencovat. No proste misto . zkus ->

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
17. 6. 2016   #57
-
0
-

Dá se vrátit pořadové číslo (index) toho iterátoru?

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #58
-
0
-

K cemu ho potrebujes? Nicmene jde udelat  it - args.begin() - vyjde ti vzdalenost

Nebo uplne kasli na iterator a indexuj vse pomoci i. Jen tam nemusis mit oboje naraz

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
17. 6. 2016   #59
-
0
-

Byl si to ty kdo říkal že mám vyndat to i že ho nepotřebuju. To tam je jen pro informaci:

std::cout << "args[" << i << "] = " << *it << std::endl;
Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #60
-
0
-

Dalsi WTF - proc v parseArguments prochazis pomoci iteratoru, ktery nepouzijes a pak jeste pocitas indexy?

+ Kdyz hodnotu ++ opravdu nepotrebujes, VZDY pouzij preinkrementaci. Post inkrementace muze byt velice draha hlavne u objektu, protoze se vytvari novy objekt.

 At delam co delam, vidim jen zminku o tom, ze nepotrebujes ten iterator, kdyz ho nikde nepouzivas.

Pak uz jen ze post inkrementace it++ je narocnejsi nez preinkrementace ++it, protoze vytvari kopii puvodni hodnoty.

(A vsude vesmes zminuju ze  this-> je ZBYTECNE a zhorsuje to citelnost kodu. Nejsme v PHP, kde se jinak k clenovi tridy ani snad nedostanes. Kdyz uz chces odlisit clenske promenne, tak jim treba muzes dat prefix m_, coz se vcelku i pouziva)

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
17. 6. 2016   #61
-
0
-

Třeba mi selhává paměť. Nevím je to tu už dlouhé. Mám m_ na stavit na this a pak to tak používat?

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #62
-
0
-

#61 oxidián
ne, jen jsem myslel neco takoveho:

class trida {
public:
  void blabla(int neco, string str) {
    m_neco = neco; // je na prvni pohled poznat, co je tridni promenna, co parametr funkce
    m_str  = str;  // pokud se budou jmenovat stejne, tak parametr funkce prekryje tridni promennou a nezbyde nic jineho nez pouzit this->
  }

private:
  int       m_neco;
  string     m_str;
};
Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
17. 6. 2016   #63
-
0
-

Ještě jsem našel jednu chybu v kódu:

value.double_ = (double) std::stoi(s);


když s je "0.01" tak výsledná hodnota se mi uloží že je 0.0000000000 ... nevíš jak to správně převést na double aby z toho nebyla 0? A stejnou věc mám i s float jen jsem ji netestoval jestli to dělá to samé, tuším že ano

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #64
-
0
-
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Kit+11
Guru
17. 6. 2016   #65
-
0
-

#63 oxidián
Zkus místo funkce stoi() použít funkci stod() bez přetypování.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Věrný člen
17. 6. 2016   #66
-
0
-

Jo tak to mě nenapadlo, že jsem to tím zkonvertováním na integer vynuloval. stoi, strof, stod - to jsou komfortní funkce, žádné trable s přetypováním :-)

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
17. 6. 2016   #67
-
0
-

#66 oxidián
ne tak vynuloval, jako odsekl desetinnou cast, tim jak se do celociselne hodnoty nema kam ulozit

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
18. 6. 2016   #68
-
0
-

#68 oxidián
to bych bud delal pomoci 0/1, nebo defaultne 0 a pokud je ten parametr nadefinovan, tak je to 1...  Jinak bys musel mit asi svoji funkci na porovnani true/false/yes/no/ano/ne/......

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Kit+11
Guru
18. 6. 2016   #69
-
0
-

#68 KIIV
Booleovské parametry obvykle předávám stylem přítomen/nepřítomen. Tedy pouze klíč bez hodnoty.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Věrný člen
23. 6. 2016   #70
-
0
-

#68 KIIV
Bylo to tady v tomto vlákně, kde si mi říkal, že není rozdíl mezi přetypováním pomocí

(type) expression

a

static_cast<type>(expression)

?

Teď jsem zjistil že v tom je velký rozdíl a to ten, že když použiju static_cast tak mi ladící program přestane vypisovat upozornění na ztrátu dat

int cStep = static_cast<int> ( std::ceil( (double) 255 / (double) size ) );

int cStep = static_cast<int> ( std::ceil( (double) (255 / size ) ) );

A to jsem fakt potřeboval protože ještě mám v živé paměti program co jsem psal snad minulý rok, kde podobných otravujících hlášek bylo snad tisíc.

K tvou posledním příspěvkům - pokud tam nejsou příklady, tak nevnímám.

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV+42
God of flame
23. 6. 2016   #71
-
0
-
Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 110 hostů

Podobná vlákna

Naco je v maine *argv[]? — založil Tom@sQo

Kontrola argumentu — založil vazbok

Pole v argumentu funkce — založil oxidián

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý