Seřazování databází a zapisování do souboru – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Seřazování databází a zapisování do souboru – C / C++ – Fórum – Programujte.comSeřazování databází a zapisování do souboru – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Tuqi
~ Anonymní uživatel
12 příspěvků
23. 3. 2013   #1
-
0
-

Ahoj, mám už nějakou dobu rozdělaný program a nemůžu s ním pohnout. Úkolem je otevřít dva souboru, na řádcích jméno - mezera - číslo, seřadit je podle abecedy a vypsat do jiného souboru tak, že pokud se shoduje jméno v 1. souboru se jménem v 2. souboru, vypíše do výstupního souboru tvar jméno-číslo v 1. souboru - číslo v 2. souboru, jinak nuly. Program sice funguje, ale ve valgrindu ukazuje memory leaky... nevím, kde: 

#ifndef __PROGTEST__
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
#endif /* __PROGTEST__ */

struct DB{
string jmeno;
int cislo;
};

#define MAX 10 
#define VETSI (pocet1 > pocet2 ? pocet1 : pocet2)

int i, j = 0, chyba = 0;

void vypocetPrvku(string radek, DB * dtbs, int j, int chyba){
    istringstream prvni(radek);
    string token;
    i = 1;
   
    while(getline(prvni, token, ' ')){
        if(i == 1) dtbs[j].jmeno = token;
        else {
            if(i == 2) 
           /* {istringstream pretyp(token); //pretypovani string > int
            int tkn;
            pretyp >> tkn;
            dtbs[j].cislo = tkn;}*/
            {
            int k;
            for(k = 0; k+1 < token.size(); k++){
                if(token[k] != '0' && token[k] != '1' && token[k] != '2' && 
                        token[k] != '3' && token[k] != '4' && token[k] != '5' &&
                        token[k] != '6' && token[k] != '7' && token[k] != '8' &&
                        token[k] != '9' && token[k] != ' ')
                { chyba = 1;
                cout << "chyba " << endl;
                break; 
                }
                
            }
            if(chyba != 1) {
              istringstream pretyp(token); //pretypovani string > int
            int tkn;
            pretyp >> tkn;
            dtbs[j].cislo = tkn;  
            }
            
            }
            }i++;}
        }



int vypocetRadku(const char * inFile, DB * dtbs, int chyba){
    
    
    ifstream in(inFile);
    string radek;
    j = 0;
    while(!in.eof()){
        getline(in, radek);
        if(in.eof() && radek.empty()) break;
       vypocetPrvku(radek, dtbs, j, chyba);
       j++;
    }
    return j;
}

DB bubblesort(DB * dtbs, int pocet){
    DB pom;
    for(i=0; i < pocet; i++) {
        for(j=0; j < pocet - i - 1; j++) {
             if(dtbs[j].jmeno > dtbs[j+1].jmeno) {
                pom = dtbs[j+1];
                dtbs[j+1] = dtbs[j];
                dtbs[j] = pom;
            }}}
    return dtbs[pocet];
}

bool joinFiles  ( const char * inFile1,
                  const char * inFile2,
                  const char * outFile )
 {
    DB dtbs1[MAX];
    int pocet1 = vypocetRadku(inFile1, dtbs1, chyba);
    cout << chyba << endl;
    if(chyba == 1) {
        cout << "aha..." << endl;
        return false;}
    DB dtbs2[MAX];
    int pocet2 = vypocetRadku(inFile2, dtbs2, chyba);
    if(chyba == 1) {
        cout << "aha..." << endl;
        return false;}
    
    for(i = 0; i < pocet1; i++) {
        cout << dtbs1[i].jmeno << "***";
        cout << dtbs1[i].cislo << endl;}
    for(i = 0; i < pocet2; i++) {
        cout << dtbs2[i].jmeno << "***";
        cout << dtbs2[i].cislo << endl;}
    cout << "*************************" << endl;
    
    for(i = 0; i < VETSI; i++) {
        for(j = i+1; j < VETSI; j++){
            if(dtbs1[i].jmeno == dtbs1[j].jmeno || dtbs2[i].jmeno == dtbs2[j].jmeno)
                return false;
        }
    }
    
    DB dtbs1b[MAX];
    DB dtbs2b[MAX];
    
    bubblesort(dtbs1, pocet1);
    bubblesort(dtbs2, pocet2);
    
    memcpy(&dtbs1b, &dtbs1, sizeof(dtbs1));
    memcpy(&dtbs2b, &dtbs2, sizeof(dtbs2));
    
    for(i = 0; i < pocet1; i++) {
        cout << dtbs1b[i].jmeno << "***";
        cout << dtbs1b[i].cislo << endl;}
    for(i = 0; i < pocet2; i++) {
        cout << dtbs2b[i].jmeno << "***";
        cout << dtbs2b[i].cislo << endl;}
    
    
    ofstream out(outFile);
    
    int a = 0, b = 0;
    
    for(i = 0; i < pocet1 + pocet2; i++){
        
            if(a == pocet1 && b == pocet2) break;
            if(a == pocet1) dtbs1b[a].jmeno = "zzz";
            if(b == pocet2) dtbs2b[b].jmeno = "zzz";
            
            if(dtbs1b[a].jmeno == dtbs2b[b].jmeno && a != pocet1 && b != pocet2){
                out << dtbs1b[a].jmeno << " " << dtbs1b[a].cislo << " " 
                        << dtbs2b[b].cislo << "\n";
                 a++;
                 b++;
                 continue;
            }
            if(dtbs1b[a].jmeno < dtbs2b[b].jmeno && a != pocet1){
                out << dtbs1[a].jmeno << " " << dtbs1[a].cislo << " 0" << "\n";
                 a++;
                 continue;
            }
            if(dtbs1b[a].jmeno > dtbs2b[b].jmeno && b != pocet2){
                out << dtbs2b[b].jmeno << " 0 " << dtbs2b[b].cislo << "\n";
                 b++;
                 continue;
            }}
            
    
    return true;
}

#ifndef __PROGTEST__
int main ( int argc, char * argv [] )
 {
    const char *inFile1 = "inA_0.txt";
    const char *inFile2 = "inB_0.txt";
    const char *outFile = "out_0.txt";
    
    joinFiles(inFile1, inFile2, outFile);
   return 0;
 }
#endif /* __PROGTEST__ */

Přijde mi, že valgrindu chybí destruktory, ale myslela jsem, že ty patří jen k příkazu new...

Díky za jakékoli rady...

Nahlásit jako SPAM
IP: 87.249.156.–
Reklama
Reklama
vitamin+8
Grafoman
23. 3. 2013   #2
-
0
-

Pouzivas memcpy() na triedu s netrivialnym konstruktorom/destructorom. std::string v destruktore uvolnuje pamet, akonahle vytvoris jeho bitovu kopiu pomocou memcpy(), tak budes mat 2 stringy ktore ukazuju do tej istej pamete, takze sa ti uvolni 2x a to je chyba. 

Riesis to strasne zlozito, jednoduhsie by to vyzeralo nasledovne:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;

struct data_t{
	long a = 0;
	long b = 0;
};

typedef std::map<std::string, data_t> db_t;

struct line_t{
	std::string name;
	long num;
	
	friend std::istream& operator>>(std::istream& in, line_t& line){
		std::string tmp;
		std::getline(in, tmp);
		//tu by sa hodilo kontrolovat spravnost retazca:
		std::stringstream ss(tmp);
		ss >> line.name >> line.num;
		return in;
	}
};

int main (){
	db_t db;
	
	std::ifstream a("a.txt");
	for(std::istream_iterator<line_t> i(a); i != std::istream_iterator<line_t>(); ++i){
		db[i->name].a = i->num;
	}
	
	std::ifstream b("b.txt");
	for(std::istream_iterator<line_t> i(b); i != std::istream_iterator<line_t>(); ++i){
		db[i->name].b = i->num;
	}

	for(db_t::iterator i = db.begin(); i != db.end(); ++i){
		std::cout << i->first << " " << i->second.a << " " << i->second.b << "\n";
	}

    
   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. "
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, 68 hostů

Podobná vlákna

Zapisování od txt souboru — založil M4rty32

Zapisování do txt — založil Reveance00

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ý