[ Šarlatan @ 16.08.2012. 11:10 ] @
Prije nego što počnem sa svojim problemom moram reći da koristim Relo2 IDE (je star, ali za studenta poput mene je dovoljan) i u njega sam spojio Borland 5.5 i najnoviji MinGW kompajlere.

Moj zadatak glasi ovako: Korisnik nasumično unosi brojeve i slova u znakovni niz. Uneseni sadržaj je potrebno pohraniti u datoteku. Nakon unosa potrebno je parne brojeve sortirati uzlazno i postaviti na početak datoteke, neparne brojeve sortirati silazno i postaviti na kraj datoteke i slova sortirati abecedno i staviti na sredinu datoteke . Također je potrebno između svakog elementa postaviti ';' kao delimiter.
Ukratko trebao bih dobiti nešto kao [parni];[slova];[neparni] u datoteci.

Ovo je kod koji sam napisao, koristio sam se dodatnim datotekama jer je to jedino funkcionalno rješenje koje sam se moga sjetiti:
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;

void uzmi_parne(fstream &destinacija, char znak) {
    if (znak == '0')
        destinacija << '0';
    if (znak == '2')
        destinacija << '2';
    if (znak == '4')
        destinacija << '4';
    if (znak == '6')
        destinacija << '6';
    if (znak == '8')
        destinacija << '8';
}

void uzmi_neparne(fstream &destinacija, char znak) {
    if (znak == '1')
        destinacija << '1';
    if (znak == '3')
        destinacija << '3';
    if (znak == '5')
        destinacija << '5';
    if (znak == '7')
        destinacija << '7';
    if (znak == '9')
        destinacija << '9';
}

void uzmi_slova(fstream &destinacija, char znak) {
    for (int i=65; i<=122; i++)
        if (znak == (char)i)
            destinacija << znak;
}

void sort_uzlazno(char array[]) {
    int N = strlen(array);
    
    for (int i=0; i<N; i++)
        for (int j=i+1; j<N; j++)
            if (array[i] > array[j])
            {
                char TEMP = array[i];
                array[i] = array[j];
                array[j] = TEMP;
            }
}

void sort_silazno(char array[]) {
    int N = strlen(array);
    
    for (int i=0; i<N; i++)
        for (int j=i+1; j<N; j++)
            if (array[i] < array[j])
            {
                char TEMP = array[i];
                array[i] = array[j];
                array[j] = TEMP;
            }
}

int main()
{
    string upis;
    
    cout << "Bezveze upisi slova i brojeve: ";
    getline(cin,upis);
    
    fstream par, nepar, slova, zad;
    
    par.open("par.txt", ios::out | ios::trunc);
    nepar.open("nepar.txt", ios::out | ios::trunc);
    slova.open("slova.txt", ios::out | ios::trunc);
    
    int size = sizeof(upis);
    for (int i=0; i<size; i++) {
        uzmi_parne(par,upis[i]);
        uzmi_slova(slova,upis[i]);
        uzmi_neparne(nepar,upis[i]);
    }
    par.close();
    slova.close();
    nepar.close();
    
    string fill;
    char *p, *s, *n;
    
    zad.open("zadatak.txt", ios::out | ios::trunc);
    
    par.open("par.txt", ios::in);
    while (!par.eof())
        getline(par,fill);
    p = new char [sizeof(fill)];
    strcpy(p, fill.c_str());
    sort_silazno(p);
    zad << p << ';';
    par.close();
    
    slova.open("slova.txt", ios::in);
    while (!slova.eof())
        getline(slova,fill);
    s = new char [sizeof(fill)];
    strcpy(s, fill.c_str());
    sort_uzlazno(s);
    zad << s << ';';
    slova.close();
    
    nepar.open("nepar.txt", ios::in);
    while (!nepar.eof())
        getline(nepar,fill);
    n = new char [sizeof(fill)];
    strcpy(n, fill.c_str());
    sort_uzlazno(n);
    zad << n ;
    nepar.close();
    
    cout << endl;
    
    zad.close();
    zad.open("zadatak.txt", ios::in);
    
    while(!zad.eof())
        getline(zad,fill);
    cout << fill << endl;
    
    cout << endl;
    system("pause");
    return 0;
}


Stvar je u tome što ovaj program radi, ali samo ako koristim Borland 5.5 kompajler, dok mi se kod MinGW kompajlera zblesira.
Primjerice, ako pri upitu bezveze ukucam
Code:
decab312645
u Borlandu dobijem točno rješenje
Code:
246;abcde;531


A u MinGW-u dobijem ovo
Code:
;acde;


Pa vas pitam: što bi li trebao promjeniti u svom kodu da mi se program izvrši kako treba u MinGW-u?
[ Mihajlo Cvetanović @ 16.08.2012. 12:08 ] @
Funkcija uzmi_slova može da se napravi i bez petlje: if (znak >= 65 && znak <= 122) destinacija << znak;. Ovo neće rešiti problem ali jeste efikasnije rešenje.

Zameni parametre funkcija sort_uzlazno i sort_silazno sa char array[] na char *array. Verovatno ni to nije rešenje, ali ko zna.

Ako je neka promenljiva x tipa string onda dužinu tog stringa dobijaš sa x.size(), a ne sa sizeof(x). To ti je definitivno deo problema. Operator sizeof se koristi da utvrdiš veličinu samog osnovnog objekta, pa ako strig sadrži pointer na bafer onda dobijaš veličinu tog pointera (recimo 4 bajta), a ne veličinu bafera na koji pointer pokazuje. Operator sizeof se obično koristi samo za osnovne tipove (int, float, char) i njihove C-ovske nizove (int[], float[], char[]), i praktično nizašta više.
[ X Files @ 16.08.2012. 12:14 ] @
Umesto:
int size = sizeof(upis);

Treba:
int size = strlen(upis.c_str());
ili:
int size = upis.length();


Inače, kod može biti i bolje koncipiran.


EDIT: Mihajlo me preduhitrio.

[ Šarlatan @ 16.08.2012. 12:38 ] @
Oboma, PUNO vam hvala!
Naredbu int size = sizeof(upis); zamjenio sam sa int size = upis.length(); iznad for-petlje za upis broja i znakova u posebne datoteke i program radi kako treba!
I hvala na objašnjenju za sizeof(), očito da moje ne znanje o toj naredbi je bio glavni problem ovdje. :P
[ Nedeljko @ 18.08.2012. 10:14 ] @
Evo ti celog rešenja, onako školski.
Code (cpp):

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

char velikoSlovo(char znak)
{
    if (znak >= 'a' && znak <= 'z') {
        return znak + 'A' - 'a';
    }

    return znak;
}

bool manje(char a, char b)
{
    return velikoSlovo(a) < velikoSlovo(b);
}

void sort(string &a)
{
    int duzina = a.size();
    bool izmena = true;

    do {
        izmena = false;

        for (int i = 1; i < duzina; ++i) {
            if (manje(a[i], a[i - 1])) {
                char pomocni = a[i - 1];

                a[i - 1] = a[i];
                a[i] = pomocni;
                izmena = true;
            }
        }
    } while (izmena);
}

int main()
{
    string upis;
    ofstream zad("zadatak.txt");

    cout << "Bezveze upisi slova i brojeve: " << flush;
    getline(cin, upis);
    sort(upis);

    for (unsigned int i = 0; i < upis.size(); ++i) {
        char znak = upis[i];

        if (znak >= '0' && znak <= '8' && (znak - '0')%2 == 0) {
            zad << znak;
        }
    }

    zad << ';';

    for (unsigned int i = 0; i < upis.size(); ++i) {
        char znak = upis[i];

        if (znak < '0' || znak > '9') {
            zad << znak;
        }
    }

    zad << ';';

    for (unsigned int i = upis.size(); i > 0; --i) {
        char znak = upis[i - 1];

        if (znak >= '1' && znak <= '9' && (znak - '0')%2 == 1) {
            zad << znak;
        }
    }

    return 0;
}