Dodawanie w systemie binarnym

0

Witam,
mam do napisania kalkulator bez ograniczeń zakresu w systemie binarnym jako projekt. Jestem początkująca i nie mogę odnaleźć błędu w swoim programie.
Na początku zajęłam się dodawaniem liczb. Mam je wczytać z pliku, zsumować parami i zapisać do pliku. Sumowanie wychodzi mi tylko, gdy wczytuje dwie liczby, dla większej ich ilości sumowanie jest nieprawidłowe. Nie wiem czy problem tkwi w pętli, w zapisie do pliku, czy w czym innym.

 #include <iostream>
 #include <string>
 #include <sstream>
 #include <fstream>
 #include <conio.h>

 using namespace std;
 
 int main()
 {
 int k=0;
stringstream liczby;
ifstream plik;
ofstream mojplik;
stringstream suma;
string l1, l2;
int i=0;   
plik.open("mojplik2.txt"); 
if(plik.good()==0) 
 {
		cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
		getch();
		return 0;
	}
	

while(plik.eof()==0)
{
getline(plik,l1);
getline(plik,l2);
cout<<l1<<endl<<l2<<endl;
k++;
}

for(int j=0;j<k;j++)
{
        for(int i = l1.size()-1; i >= 0; i--)
        {
            liczby << l1[i];
            }
        l1 = liczby.str();
        liczby.str("");
        
        for(int i = l2.size()-1; i >= 0; i--)
            liczby << l2[i];
        l2 = liczby.str();
        liczby.str("");
        
        int max;
        
        if(l1.size()>=l2.size())
        max=l1.size();
        else max=l2.size();
        
   
    int podsuma, dod = 0;
    
    for(int i = 0; i < max; i++)
    {         
        if(l1.size() > i && l2.size() > i)
        podsuma = (char)l1[i]-48 + (char)l2[i]-48;
        else{
             if (l1.size() > l2.size())
             podsuma=(char)l1[i]-48;
             else
             podsuma=(char)l2[i]-48;
             }
        podsuma=podsuma+dod;
        
            if(podsuma > 1)
            {
                dod = 1;
                suma<<podsuma%2;
            }
            else{ 
                suma << podsuma;  
                dod = 0;
            }
        }
        cout<<endl;
        if(dod==1)
        suma << dod;
        }
        string wynik;
        wynik = suma.str(); 
        cout<<"wynik"<<endl;

          mojplik.open("abc.txt");
          for(int j=0;j<k;j++)
          {    
        for(int i = wynik.size()-1; i >= 0; i--)
       {
        mojplik << wynik[i];
        cout<<wynik[i];
        }
        cout<<endl;
        }            
        mojplik.close();
       
 system("pause");
 return 0;
 }

Bardzo proszę o pomoc. Sama już nie mam pomysłu, co tu zmienić.

0

Ale co się dzieje jak wczytasz więcej niż 2 liczby? program się zamyka? Masz nieprawidłowy wynik? Opisz dokładniej.

0

Wszystko wpakowałaś do main, zamiast podzielić na podfunkcje (lepiej się czyta, analizuje).
Poniżej dodaje komentarze co mi się rzuca w oczy:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <conio.h>

using namespace std;

int main()
{
    int k=0;
    stringstream liczby;
    ifstream plik;
    ofstream mojplik;
    stringstream suma;
    string l1, l2;
    int i=0;   
    plik.open("mojplik2.txt"); 
    if(!plik.good()) 
    {
        cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
	getch();
	return 0;
    }

    while(plik.eof()==0) // tak się nie robi, lepiej przenieść tu pierwszego getline: while(getline(plik,l1)) 
    {
        getline(plik,l1); // jeśli pętla wykonuje się więcej niż raz to co? Tracisz dane z wcześniejszych linii, bo nadajesz l1 i l2 nowe wartości!
        getline(plik,l2);
        cout<<l1<<endl<<l2<<endl;
        k++;
    }
    
    for(int j=0;j<k;j++) // to nie ma sensu z powodu powyżej
    {
...

Masz 2 wyjścia:
#wpakować sumowanie do pętli wczytującej (najlepiej zrób funkcję string suma(const string &a,const string &b))
#zamienić l1 i l2 na tablicę stringów i zapamiętywać kolejne wartości

0
MarekR22 napisał(a)

Wszystko wpakowałaś do main, zamiast podzielić na podfunkcje (lepiej się czyta, analizuje).
Poniżej dodaje komentarze co mi się rzuca w oczy:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <conio.h>

using namespace std;

int main()
{
    int k=0;
    stringstream liczby;
    ifstream plik;
    ofstream mojplik;
    stringstream suma;
    string l1, l2;
    int i=0;   
    plik.open("mojplik2.txt"); 
    if(!plik.good()) 
    {
        cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
	getch();
	return 0;
    }

    while(plik.eof()==0) // tak się nie robi, lepiej przenieść tu pierwszego getline: while(getline(plik,l1)) 
    {
        getline(plik,l1); // jeśli pętla wykonuje się więcej niż raz to co? Tracisz dane z wcześniejszych linii, bo nadajesz l1 i l2 nowe wartości!
        getline(plik,l2);
        cout<<l1<<endl<<l2<<endl;
        k++;
    }
    
    for(int j=0;j<k;j++) // to nie ma sensu z powodu powyżej
    {
...

Masz 2 wyjścia:
#wpakować sumowanie do pętli wczytującej (najlepiej zrób funkcję string suma(const string &a,const string &b))
#zamienić l1 i l2 na tablicę stringów i zapamiętywać kolejne wartości

Dziękuję bardzo za odpowiedź. W sumie u siebie w programie mam to podzielone na funkcje, ale mam tam jeszcze inne elementy, więc żeby było szybciej, tutaj wrzuciłam wszystko do maina. Chciałabym jeszcze poprosić o bliższe wyjaśnienie tego, jak wpakować sumowanie do pętli wczytującej, bo na razie chyba nie załapałam o co chodzi. To mój pierwszy raz z wczytywaniem i zapisywaniem do pliku, wcześniej tego nie robiłam i nie wiem czy kompletnie to już załapałam ;)

0
while(getline(plik,l1)) {
    if (getline(plik,l2))
        cout << l1 << " + " << l2 << " = " << sumaBinarnie(l1,l2) << endl;
}
0

Dzięki prześliczne - teraz w końcu wczytuje i wypisuje dobre wyniki.
Pojawił się tylko problem z zapisem do pliku - zapisuje mi tylko ostatni wynik. Co zrobić żeby zapisywało wszystkie wyniki? I jeszcze jedno - jeśli stosuję instrukcję switch, to czy przy rozważaniu każdego przypadku mogę otworzyć i zamknąć plik, a potem na nowo go otworzyć? Bo jeśli chcę wykonać najpierw dodawanie liczb zapisanych w pliku, a następnie ich odejmowanie, to wygląda na to, że przy odejmowaniu nie może odnaleźć pliku, z którego ma wczytać dane.
Poniżej wklejam fragment kodu z instrukcją switch (przepraszam, trochę dużo mam znowu w tym mainie nawalone).

int main()
{  
        string l1, l2;  
int n;
do
{
menu(); 
cin>>n;
switch(n)
{
         case 1:
              {
                    plik.open("mojplik2.txt"); 
if(plik.good()==0) 
 {
		cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
		getch();
		return 0;
	}   
	
while(getline(plik,l1))
{
if (getline(plik,l2)){
                      cout<<endl;
        cout<< l1 << " + " << l2 << " = ";
        sumowanie(l1,l2);
                string wynik;
        wynik = suma.str(); 
        mojplik.open("abc.txt");
        for(int i = wynik.size()-1; i >= 0; i--)
       {
        mojplik << wynik[i];
        cout<<wynik[i];
        }
        cout<<endl;
        suma.str("");
        }
        else cout<< " nie podano dwoch liczb - dzialanie nie zostanie wykonane!"<<endl;}
                mojplik.close();
                }
        break;
        
         case 2:
              {
                  plik.open("mojplik2.txt"); 
if(plik.good()==0) 
 {
		cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
		getch();
		return 0;
	}                 
              while(getline(plik,l1))
{
if (getline(plik,l2))
{
                     if(l1.size()>l2.size())
        cout<<l1 << " - " << l2 << " = ";
        else cout<<l2<< " - " <<l1<< " = ";
        
        odejmowanie(l1,l2);
        cout<<endl;
        string wynik = roznica.str(); 
         ofstream mojplik;
          mojplik.open("abcd.txt");     
        for(int i = wynik.size()-1; i >= 0; i--){
        mojplik << wynik[i];
        cout<<wynik[i];
        }
        cout<<endl;
        
        roznica.str("");
        }
        else cout<< " nie podano dwoch liczb- dzialanie nie zostanie wykonane!"<<endl;}
        mojplik.close();
        }
        break;
         case 3:break;
         case 4:break;
         default:cout<<"Wpisano niewlasciwy numer operacji\n";break;
}
}
while(n!=4);
     
 system("PAUSE");
 return 0;   
}

0

#Formatuj kod starannie (od tego są programy, które to robią automatycznie)! Taki jest lepiej:

int main()
{  
    string l1, l2;  
    int n;
    do
    {
        menu(); 
        cin>>n;
        switch(n)
        {
        case 1:
        {
            plik.open("mojplik2.txt"); 
            if(plik.good()==0) 
            {
                cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
                getch();
                return 0;
            }   
            
            while(getline(plik,l1))
            {
                if (getline(plik,l2)){
                    cout<<endl;
                    cout<< l1 << " + " << l2 << " = ";
                    sumowanie(l1,l2);
                    string wynik;
                    wynik = suma.str(); 
                    mojplik.open("abc.txt");  // otwierasz plik wewnątrz pętli
                    for(int i = wynik.size()-1; i >= 0; i--)
                    {
                        mojplik << wynik[i];
                        cout<<wynik[i];
                    }
                    cout<<endl;
                    suma.str("");
                }
                else cout<< " nie podano dwoch liczb - dzialanie nie zostanie wykonane!"<<endl;
            }
            mojplik.close();
        }
        break;
        
        case 2:
        {
            plik.open("mojplik2.txt"); 
            if(plik.good()==0) 
            {
                cout<<"Wystapil problem zwiazany z plikiem, program zostanie zamkniety\n";
                getch();
                return 0;
            }                 
            while(getline(plik,l1))
            {
                if (getline(plik,l2))
                {
                    if(l1.size()>l2.size())
                        cout<<l1 << " - " << l2 << " = ";
                    else cout<<l2<< " - " <<l1<< " = ";
                    
                    odejmowanie(l1,l2);
                    cout<<endl;
                    string wynik = roznica.str(); 
                    ofstream mojplik;
                    mojplik.open("abcd.txt");     
                    for(int i = wynik.size()-1; i >= 0; i--){
                        mojplik << wynik[i];
                        cout<<wynik[i];
                    }
                    cout<<endl;
                    
                    suma.str("");
                }
                else cout<< " nie podano dwoch liczb- dzialanie nie zostanie wykonane!"<<endl;
            }
            mojplik.close();
        }
        break;
        case 3:break;
        case 4:break;
        default:cout<<"Wpisano niewlasciwy numer operacji\n";break;
        }
    }
    while(n!=4);
    
    system("PAUSE");
    return 0;   
}

#Jeszcze raz! DZIEL wszystko na małe funkcje! Unikniesz takiego magla i nie będziesz robić takich błędów! Jeśli coś ci się zrobi dłuższe niż 10-20 linii znaczy, że jest za długie! Przykładowo aż się prosi, żeby każdy case w switch miał swoją funkcję (nawet łatwo wymyśleć nazwę, menu to powinno dobrze zasugerować).
#otwierasz plik wielokrotnie w pętli (plik zmieniany jest w stan błędu i nic się nie zapisuje od drugiej iteracji.

0

Czyli powinnam otworzyć oba pliki (ten, z którego wczytuję wyniki i ten, do którego zapisuję wyniki) jeszcze przed instrukcją switch? Co zrobić z zamykaniem plików - też zamknąć dopiero po wyjściu ze switcha? Gdy postępuję w ten sposób, w pliku nic mi się nie zapisuje i nie mogę wykonać dwóch działań przy jednym otwarciu programu.
Obiecuję poprawić się na przyszłość z zapisem. Chociaż tyle mogę zrobić - wielkiej programistki ze mnie nie będzie, ale uważam, że studia zobowiązują mnie do uzyskania elementarnej wiedzy w tym zakresie. :)

edit// W sumie, gdy otworzyłam przed pętlami 4 różne pliki (w każdym case inny do odczytu i zapisu danych) to wszystko pięknie działa, ale czy dałoby się to wszystko odczytywać z jednego pliku i zapisywać do drugiego pliku? To byłby szczyt moich oczekiwań, ale zaczynam wątpić, czy to jest fizycznie możliwe, bo nie wiem jak to wykombinować.

0
kachna napisał(a)

Czyli powinnam otworzyć oba pliki (ten, z którego wczytuję wyniki i ten, do którego zapisuję wyniki) jeszcze przed instrukcją switch?

NIE! Przeczytaj moją odpowiedź jeszcze raz!

0

Przeczytałam i dużo z niej nie wyniosłam, bo nawet jak otwieram plik poza pętlą, ale w instrukcji switch, to program nie działa tak jak powinien, ale jego działanie we wcześniej wspomnianym stanie (wczytywanie z oddzielnych plikow) też uznaję za znośne. Tak czy inaczej bardzo dziękuję za te wszystkie odpowiedzi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1