Diskuze: Přepsání argumentu ve vláknu
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.


Martin Dráb:7.12.2016 22:57
Předávej ty listy referencí, ne hodnotou. Takhle se celé zkopírují a tyto kopie se pak použijí jako argumenty těch funkcí sort. Změny se nepropagují zpátky.
Mohlo by stačit změnit signatury těch funkcí nějak takto:
void sort(char sign, list<string> & l)
void sortZA(list<string> & lst)
Podobně to můžeš udělat u compareNoCase, pokud to překladač sežere. Protože takhle při každeém porovnávání ty řetězce kopíruješ, což není zrovna nenáročná operace.
bool compareNoCase(const string & first, const string & second)
+20 Zkušeností
+2,50 Kč

Aha problém je v tom, že
ta daná funkce nefunguje ve vláknu. Lze jiným způsobem vytvořit
vlákno?
Ano, už vyřešeno. Děkuji Vám
Oldřich Beneš:13.12.2016 20:04
Zdravím, vyskytl se mi problém, mám napsaný kód, který se mi zdál funkční, ale dnes při kontrole mi bylo řečeno, že nefunguje správně, nevrací stejný počet jmen a mám prý někde problém se sortem... Čučím na to už 5 hodin a na nic jsem nepřišel. Nekoukl by mi na to někdo prosím ?
// LuldaOS.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <ios>
#include <string.h>
#include <string>
#include <list>
#include <windows.h>
using namespace std;
//převzato z http://www.cplusplus.com/forum/beginner/12089/
bool compareNoCase(string first, string second)
{
unsigned int i = 0;
while ((i < first.length()) && (i < second.length()))
{
//v if a else if pouze porovnává jednotlivé znaky slov, když je jedno z nich menší/větší vrátí true/false, ukončí cyklus....
//když jsou písmena rovna, zvýším si index pro pohyb v "poli" a pokračuju dál v cyklu
if (tolower(first[i]) < tolower(second[i])) return true;
else if (tolower(first[i]) > tolower(second[i])) return false;
i++;
}
//v případě, že budou stejná písmena vrátí kratší slovo, v případě že je první kratší/true
if (first.length() < second.length()) return true;
else return false;
}
//metoda pro samotné třídění, jako parametr bere znak, jak třídit a samotný list
void sort(const char sign, list<string> &lst) {
//ověření, zda je znak v nebo s, provedu sort
if (sign == 'v' || sign == 's') {
lst.sort(compareNoCase);
//když chceme třídit sestupně převrátím předchozí sort
if (sign == 's') lst.reverse();
}
}
//metoda pro slívání dvou listů(2první arg), následně znak třídění, cestu k výstupnímu souboru
void sliti(list<string> &l1, list<string> &l2, const char sign, const char * path) {
FILE * output;
output = fopen(path,"w+");
//porovnávám, jak mám třídit, když vzestupně nastavím sort na false... viz další kroky
bool sort = false;
if (sign == 'v') {
//vzestupně
sort = true;
}
int pokus = 0;
size_t ctemp;
while (true) {
//ověřuji zda není jeden z listů prázdný
if (l1.size() == 0 && l2.size() == 0) break;
if (l1.size() > 0 && l2.size() > 0) {
if (sort) {
//porovnávání prvních slov z listů
if (compareNoCase(l1.front(), l2.front())) {
ctemp = l1.front().length(); //zjistím délku slova
fprintf(output, "%x%s", ctemp,l1.front().c_str()); //tisk délky slova a samotného slova
l1.pop_front(); // ostranění prvku z listu
pokus++;
}
else {
ctemp = l2.front().length();
fprintf(output, "%x%s", ctemp, l2.front().c_str());
l2.pop_front();
pokus++;
}
}
else {
if (!compareNoCase(l1.front(), l2.front())) {
ctemp = l1.front().length();
fprintf(output, "%x%s", ctemp, l1.front().c_str());
l1.pop_front();
pokus++;
}
else {
ctemp = l2.front().length();
fprintf(output, "%x%s", ctemp, l2.front().c_str());
l2.pop_front();
pokus++;
}
}
}
//tady nastal případ že jeden z listů je prázný => vypíšu zbytek druhého listu do výstupu...
//l1 je prázný => vypíšu l2
else if (l1.size() == 0 && l2.size()>0) {
for (unsigned int i = l2.size(); i > 0; i--) {
ctemp = l2.front().length();
fprintf(output, "%x%s", ctemp, l2.front().c_str());
l2.pop_front();
pokus++;
}
}
//l2 je prázdný vypíšu zbytek l1
else if (l2.size() == 0 && l1.size() > 0) {
for (unsigned int i = l1.size(); i > 0; i--) {
ctemp = l1.front().length();
fprintf(output, "%x%s", ctemp, l1.front().c_str());
l1.pop_front();
pokus++;
}
}
}
int b = pokus;
fclose(output);
}
//cesta k souboru, list 1, list 2
void nactiJmena(string path, list<string> &l1, list<string> &l2) {
char temp[45]; //buffer pro načítání jmen ze souboru
FILE * file;
file = fopen(path.c_str(), "r");
//list do kterého se načtou všechna jména
list<string> templist;
while (!feof(file)) {
//zjistím si délku slova
char word_length = getc(file);
//vyzkouším načíst daný počet znaků ( jméno )
if (fgets(temp, word_length + 1, file)) {
string s(temp);
templist.push_front(s);
}
}
fclose(file);
//rozdělení do dvou listů
int index = 0;
while (templist.size() > 0) {
if (index % 2 == 0) {
l1.push_front(templist.front());
templist.pop_front();
}
else {
l2.push_front(templist.front());
templist.pop_front();
}
index++;
}
}
int main(int argc, char* argv[])
{
//načtení parametrů z konzole
string pathin = argv[1];
string pathout = argv[2];
char * sortsign = argv[3];
//listy sloužící pro ukládání načtených jmen
list<string> mylist1;
list<string> mylist2;
nactiJmena(pathin, std::ref(mylist1), std::ref(mylist2));
thread first(sort, sortsign[0], std::ref(mylist1));
thread second(sort, sortsign[0], std::ref(mylist2));
//počkání na ukončení práce vláken
first.join();
second.join();
//provedení slití
sliti(mylist1, mylist2, sortsign[0], pathout.c_str());
cout << "Aplikace ukončila práci, zadejte libovolný znak a stiskněte enter" << endl;
getchar();
return 0;
}
Zobrazeno 7 zpráv z 7.