Výpis z řetězce – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Výpis z řetězce – C / C++ – Fórum – Programujte.comVýpis z řetězce – C / C++ – Fórum – Programujte.com

 

Dzanek0
Duch
6. 12. 2012   #1
-
0
-

Zdravím, jsem začátečník a potřebuji poradit, jak sestavit algoritmus, který mi z řetězce obsahující čísla a intervaly oddělené od sebe čárkou vypíše všechny čísla zvlášť. V řetězci může být mezi čísly libovolný počet bílých znaků. Např. řetězec: "93   ,2,   12-20".

A potřebuji z toho řetězce dostat čísla: "93"  a  "2"  a  "12"  a  "20"  . Tyto získané čísla nemusí být typu "int", stačí když budou typu "char". Převod z "int" na "char" už mám vyřešený.

Nahlásit jako SPAM
IP: 90.176.193.–
zlz
~ Anonymní uživatel
634 příspěvků
6. 12. 2012   #2
-
0
-

To už se tady (i jinde) řešilo. Zkus pohledat. Řada číslic tvoří číslo, zbytek je oddělovač, v něm ignoruješ mezery a zajímá tě, jestli je tam čárka, nebo pomlčka.

Nahlásit jako SPAM
IP: 78.156.159.–
Michal
~ Anonymní uživatel
683 příspěvků
6. 12. 2012   #3
-
0
-

   

#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    string cislo[50];
    int j=0;
    string retazec = "93   ,2,   12-20";
    int VelRetazca=retazec.size();
    for(int i=0;i<VelRetazca;i++)
    {
            if(isdigit(retazec[i]))
            {
                 while(isdigit(retazec[i]))  
                 {
                     cislo[j]=cislo[j]+retazec[i];
                     i++;
                 }  
                 j++;              
            }                      
    }
    cout << cislo[2];
    cin.get();
  return 0;

Drobnosti si už uprav.

Michal F.


Nahlásit jako SPAM
IP: 87.244.233.–
Michal
~ Anonymní uživatel
683 příspěvků
6. 12. 2012   #4
-
0
-

#3 Michal
Ako tak pozerám ,  mám tam pár chybičiek , na konci chýba ' } ' ,  číslo , ktoré chceš je typu string , čísluje sa od [0] , číže prvé číslo z toho reťazca je cislo[0] atd.. , v tomto príklade je to pre max 49 čisel.

S pozdravom Michal

Nahlásit jako SPAM
IP: 87.244.233.–
vitamin+8
Grafoman
6. 12. 2012   #5
-
+1
-
Zajímavé

alebo:

#include <cstdio>
#include <iostream>
using namespace std;


int main(){
	char str[] = "93,2,  \t\t 12-\t20";
	int num[4];
	
	if(sscanf(str, "%d , %d , %d - %d", num, num+1, num+2, num+3)!=4){
		cout << "chyba" << endl;
		return EXIT_FAILURE;
	}
	
	cout << num[0] << endl << num[1] << endl << num[2] << endl << num[3] << endl;
	
	return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Dzanek0
Duch
6. 12. 2012   #6
-
0
-

Michale díky za snahu ale tvůj algoritmus mi nefunguje, vypíše mi to první číslo a pak nějaké paskvily.

vitamin: Super díky, tvůj algoritmus je to co jsem hledal. Ale ještě jedna drobnost, kterou jsem zapomněl napsat: Ve vstupním řetězci může těch čísel být více i méně než 4, může tam být jedno, nebo jich tam může být i 50.

Nahlásit jako SPAM
IP: 90.176.193.–
Dzanek0
Duch
6. 12. 2012   #7
-
0
-

A ještě jedna věc: Nešlo by to nějak ošetřit v případě kdy je ve vstupu interval, tzn jsou tam 2 čísla mezi kterýma je pomlčka "-", tak aby byly tyto dvě čísla po proběhnutí tvého cylku na sebe nějak "napojená"? Protože dále budu muset pracovat i se všemi čísly, které se nachází uvnitř toho intervalu.

Nahlásit jako SPAM
IP: 90.176.193.–
MISSHO0
Duch
6. 12. 2012   #8
-
0
-

Mne ten zdrojak v pohode funguje , nechápem. Načmárané narýchlo v devCpp. čo máš na mysli pod pojmom napojené?

Nahlásit jako SPAM
IP: 87.244.233.–
zlz
~ Anonymní uživatel
634 příspěvků
6. 12. 2012   #9
-
0
-

   

"1, 3-6, 8" => { 1, 3, 4, 5, 6, 8 }
Nahlásit jako SPAM
IP: 80.188.216.–
Dzanek0
Duch
6. 12. 2012   #10
-
0
-

Protože budu dál v programu počítat s každým číslem v zadaném intervalu. Takže když bude např. interval 12-20, tak budu počítat s čísly 12,13,14,15,16,17,18,19,20 (s každým číslem zvlášť). Interval by se dal vyřešit cyklem for:

int num[N], j=0;

int dolniMez = 12;

int horniMez = 20;

for(int i=dolniMez; i<horniMez+1; i++) {

    num[j]=i+...počítání ...;

    j++;

}

Ale jde mi o to, jak to naprogramovat aby ten cyklus for poznal jaká je dolní a horní mez toho intervalu?

Možná to bude chtít podmínku: jestli je v řetězci mezi dvěma čísly pomlčka "-" tam to první číslo (nalevo) je dolní mez intervalu a to druhé číslo je horní mez intervalu.

Ale bohužel jsem nepřišel na to jak sestavit tuhle podmínku aby správně fungovala.

Nahlásit jako SPAM
IP: 90.176.193.–
zlz
~ Anonymní uživatel
634 příspěvků
Nahlásit jako SPAM
IP: 80.188.216.–
vitamin+8
Grafoman
6. 12. 2012   #12
-
0
-

#10 Dzanek
skus toto:

#include <iostream>
#include <string>
#include <set>
#include <cctype>
#include <sstream>
using namespace std;


unsigned str2uint(const string& str){
	stringstream s(str);
	unsigned u;
	s >> u;
	return u;
}

bool spracuj(string str, set<unsigned>& out){
	str += ' ';
	string::const_iterator cislo;
	unsigned temp;
	
	enum state_t{Begin, Cislo, Medzera, IntervalBegin, IntervalCislo, IntervalMedzera, End};
	
	state_t stav = Begin;
	
	for(auto i = str.cbegin(); i != str.cend(); ++i)
		switch(stav){
			case Begin:	
				if(isdigit(*i)){
					cislo = i;
					stav = Cislo;
				}
				else if(!isspace(*i))return false;
				break;
			case Cislo:	
				if(isspace(*i)){
					out.insert(temp = str2uint(string(cislo, i)));
					stav = Medzera;
					}
				else if(*i == ','){
					out.insert(temp = str2uint(string(cislo, i)));
					stav = End;
				}
				else if(*i == '-'){
					out.insert(temp = str2uint(string(cislo, i)));
					stav = IntervalBegin;
				}
				else if(!isdigit(*i))return false;
				break;
			case Medzera:
				if(*i == ',')stav = End;
				else if(*i == '-')stav = IntervalBegin;
				else if(!isspace(*i))return false;
				break;
			case IntervalBegin:	
				if(isdigit(*i)){
					cislo = i;
					stav = IntervalCislo;
				}
				else if(!isspace(*i))return false;
				break;
			case IntervalCislo:	
				if(isspace(*i)){
					unsigned u = str2uint(string(cislo, i));
					if(u < temp)return false;
					for(;temp <= u; ++temp)
						out.insert(temp);
					stav = IntervalMedzera;
					}
				else if(*i == ','){
					unsigned u = str2uint(string(cislo, i));
					if(u < temp)return false;
					for(;temp <= u; ++temp)
						out.insert(temp);
					stav = End;
				}
				else if(!isdigit(*i))return false;
				break;
			case IntervalMedzera:
				if(*i == ',')stav = End;
				else if(!isspace(*i))return false;
				break;
			case End:	
				if(isdigit(*i)){
					cislo = i;
					stav = Cislo;
				}
				else if(!isspace(*i))return false;
				break;
	}

	return (stav == Begin || stav == Medzera || stav == IntervalMedzera);
}


int main(){
	
	set<unsigned> v;
	
	
	if(spracuj("22,  1-4, 1,2- 4, 9 -11", v)){
		cout << "interval obsahuje cisla:\n";
		for(auto a : v)cout << a << ", ";
	}
	else{
		cerr << "chyba";
		return EXIT_FAILURE;
	}	
		
	return EXIT_SUCCESS;


}
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Dzanek0
Duch
7. 12. 2012   #13
-
0
-

Co je to prosimtě typ "auto"? V mainu ve 4. řádku? Visual Studio mi červeně podtrhlo for(auto a : v)cout << a << ", "; (podtžené jsou: "a", ":", ")").

U "a" to píše: Error: cannot deduce 'auto' type (initializer required),

u ":" to píše: Error: Expected a ';'

u ")" to píše: Error: expected an expression

Nahlásit jako SPAM
IP: 2001:718:1001:700:200:5ef...–
vitamin
~ Anonymní uživatel
1092 příspěvků
7. 12. 2012   #14
-
0
-

Akú máš verziu VS? (od VS2010 by mal fungovat foreach)

Nahlásit jako SPAM
IP: 195.28.77.–
vitamin
~ Anonymní uživatel
1092 příspěvků
7. 12. 2012   #15
-
0
-

#14

Tak som to vyskúšal vo VS2010 a zrejme nepozná foreach, pouzi"

for(auto i = v.begin(); i != v.end(); ++i)
	cout << *i << ", ";

Nahlásit jako SPAM
IP: 195.28.77.–
Dzanek0
Duch
7. 12. 2012   #16
-
0
-

Mám VS2010.

Už to funguje správně. Ale mám ještě jeden problém.

Do tohoto cyklu for jsem vložil funkci atoi() (na převod z char to int) a funkci vypocet(), která pracuje i s proměnnou x. 

for(auto i = v.begin(); i != v.end(); ++i)
  {
   cout << *i << ", ";
   x = atoi(i);
   vypocet(x, n, p);
  }

Jenže při sestavování dojde k chybě:

error C2664: 'atoi' : cannot convert parameter 1 from 'std::_Tree_const_iterator<_Mytree>' to 'const char *'
1>          with
1>          [
1>              _Mytree=std::_Tree_val<std::_Tset_traits<unsigned int,std::less<unsigned int>,std::allocator<char32_t>,false>>
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

A s tímhle si bohužel neporadím.

Nahlásit jako SPAM
IP: 90.176.193.–
vitamin+8
Grafoman
7. 12. 2012   #17
-
0
-

Premenna 'v' je kontainer ktory obsahuje cisla ktore si zadal v stringu. Uz nemusis nic konvertovat.

V podstate funkcia spracuj() ma 2 parametre, jeden je string ktory chces spracovat a dalsi je referencia na kontainer do ktoreho zapises vsetky cisla ktore definuje string. Vracia true ak nenastala chyba.

Ak chces pochopit tomu kodu, tak sa budes musiet naucit pouzivat stl kontainery (aspon zaklady). 

edit:

Ta tvoja uloha je pre zaciatocnika dost tazka, mozno by nebolo odveci zcat s niecim lahsim a k tomuto sa vratit neskor.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Dzanek0
Duch
7. 12. 2012   #18
-
0
-

Aha, tak jak mám do funkce vypocet() zadat parametr - číslo z řetězce?

zkoušel jsem vypocet(v, n, p)  a pak i   vypocet(v[i], n, p)  ale oba zapisy jsou špatně protože program nefunguje.

Nahlásit jako SPAM
IP: 90.176.193.–
vitamin+8
Grafoman
7. 12. 2012   #19
-
0
-

#18 Dzanek
asi takto:

vypocet(*i, n, p);	//nepoznam prototyp funkcie, takze len tipujem :)
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Dzanek0
Duch
7. 12. 2012   #20
-
0
-

Funkce přijme hodnotu proměnné 'x', provede výpočet a vrátí hodnoty proměnných 'n' a 'p'. Pak proměnné 'x', 'n' a 'p' zapíšu do souboru formátu HTML. Tohle už naštěstí mám vyřešené.

void vypocet(int x, int &n, int &p)
{
int a, b, c, d, e, g, h, m, j, k, l;
a=x%19;
b=x/100;
c=x%100;
d=b/4;
e=b%4;
g=((8*b)+13)/25;
h=((19*a)+b-d-g+15)%30;
m=(a+(11*h))/319;
j=c/4;
k=c%4;
l=((2*e)+(2*j)-k-h+m+32)%7;
n=(h-m+l+90)/25;
p=(h-m+l+n+19)%32;
}

Jinak ti moc děkuji za pomoc, už to funguje jak má.

Nahlásit jako SPAM
IP: 90.176.193.–
Atheo+4
Stálý člen
9. 12. 2012   #21
-
0
-

#1 Dzanek
Ahoj, nevím jak se to přesně dělá v C++ ale v C# se na to používá metoda Split. Např:

string[] rozdel = mujstring.Split(';'); // pokud je to rozdělené pomocí středníku
// no a pak už jen
rozdel[0] // tam je uložená první hodnota před středníkem
rozdel[1] // tam je druha hodnota před druhým středníkem

a tak dále v C/C++ bude nejspíše podobná metoda. 

Tomáš (nečetl jsem všechny příspěvky možná to tu už dávno je)  

Nahlásit jako SPAM
IP: 188.175.140.–
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, 149 hostů

Podobná vlákna

[VB] řetězce — založil aTTix

řetězce — založil ench

řetězce — založil ench

Moderátoři diskuze

 

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