Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zapisanie do pliku .txt kilku wartosci powoduje koniecznosc ponownego podania parametrow

Ostatnio zmodyfikowano 2016-07-06 15:23
Autor Wiadomość
AterVulpes
Temat założony przez niniejszego użytkownika
Zapisanie do pliku .txt kilku wartosci powoduje koniecznosc ponownego podania parametrow
» 2016-07-05 13:48:16
Witam.

Zabawe z C++ zaczalem bardzo niedawno (tydzien-dwa temu) i natrafilem na pewien problem.
Mianowicie, kiedy chce, by program zapisal wyniki obliczen do pliku txt, pewne f-cji w program uaktywniaja sie po raz drugi. Ponizej wklejam kod programu. Pod nim opisze problem dokladniej.


C/C++
//calculates lattice parameters and outputs a txt file with them

#include <iostream>
#include <math.h>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <fstream>

#define M_PI 3.14159265358979323846

int millerIndexH()
{
    int h;
    std::cout << "Input h index" << std::endl; //input of Miller index h
    std::cin >> h;
    return h;
}

int millerIndexK()
{
    int k;
    std::cout << "Input k index" << std::endl; //input of Miller index k
    std::cin >> k;
    return k;
}

int millerIndexL()
{
    int l;
    std::cout << "Input l index" << std::endl; //input of Miller index l
    std::cin >> l;
    return l;
}

long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa\n 2 - CrKa\n 3 - FeKa\n 4 - CoKa\n 5 - MoKa\n 6 - AgKa\n 0 - other\n";
    std::cout << "Choose source: ";
    int choice;
    std::cin >> choice;
    std::cout << "\n";
   
    if( choice == 1 )
    {
        long double wl;
        wl = 1.5406;
        return wl;
    }
    if( choice == 2 )
    {
        long double wl;
        wl = 2.29;
        return wl;
    }
    if( choice == 3 )
    {
        long double wl;
        wl = 1.94;
        return wl;
    }
    if( choice == 4 )
    {
        long double wl;
        wl = 1.79;
        return wl;
    }
    if( choice == 5 )
    {
        long double wl;
        wl = 0.71;
        return wl;
    }
    if( choice == 6 )
    {
        long double wl;
        wl = 0.56;
        return wl;
    }
    if( choice == 0 )
    {
        std::cout << "Input wavelength" << std::endl;
        long double wl;
        std::cin >> wl;
        return wl;
    }
    return 0;
}

long double doubleThetaDegrees() //takes double theta angle in degrees
{
    long double t_deg;
    std::cout << "Input double theta in degrees" << std::endl;
    std::cin >> t_deg;
    std::cin.ignore(); //placing it in main() right before cin.get() does diddly squat
    return t_deg;
}

long double tInRadians() //converts theta() from degrees to radians
{
    long double t_deg = doubleThetaDegrees();
    long double t_rad;
    t_rad =(( t_deg ) / 2 ) *( M_PI / 180 );
    return t_rad;
}

long double latticeSpacing() //calculate lattice spastd::cing
{
    long double wl = defineWaveLength();
    long double t_rad = tInRadians();
    long double d;
    d =( wl /( 2 * sin( t_rad ) ) );
    return d;
}

long double latticeConstantCalculation() //calculate the constant
{
    int h = millerIndexH();
    int k = millerIndexK();
    int l = millerIndexL();
    long double d = latticeSpacing();
    long double a;
    a = sqrt(( pow( h, 2 ) + pow( k, 2 ) + pow( l, 2 ) ) *( pow( d, 2 ) ) ); //proper equation
    return a;
}

int main()
{
    int h = millerIndexH();
    int k = millerIndexK();
    int l = millerIndexL();
    long double d = latticeSpacing();
    long double a = latticeConstantCalculation();
    std::cout << "(" << h << k << l << ")" << "\t" << a << "\t" << d << std::endl; //shows result
    std::ofstream o( "Lattice Parameters.txt", std::ios::app );
    o << "Miller indecies (" << h << k << l << ")/tLattice Constant " << a << "\tLattice spacing " << d << std::endl;
    std::cin.get();
}

Pod main() jest lista:
C/C++
int h = millerIndexH();
int k = millerIndexK();
int l = millerIndexL();
long double d = latticeSpacing();
long double a = latticeConstantCalculation();
Jest ona, poniewaz chce, by w pliku wyjsciowym znalazla sie linijka tekstu np:
(110)tab3.807tab2.690
Liczby w nawiasie to hkl, 3.807 to a, 2.690 to d.
Jesli z tej listy usune wszystkie int oraz latticeSpacing(), wtedy wszystko dziala poprawnie (czyli musze podac parametry tylko raz), ale do pliku nie sa zapisywane wszystkie informacje. To rozumiem, nie wszystkie sa wywolywane i z cout << musze je pousuwac, inaczej kompilator wskaze je jako niezadeklarowane.
Jesli jest tak, jak jest, wtedy musze podawac wszystkie parametry wiecej niz raz.

Czy zamiast identyfikowac f-cji, z ktorej brana jest zmienna, wymuszam jej ponowne dzialanie ? Ale jesli tak, to dlaczego gdy jest tylko linijka
C/C++
long double a = latticeConstantCalculation();
to jest wszystko w porzadku ?

Pozdrawiam i dziekuje za cierpliwosc.

[edit1]
Usunalem nadmiarowy #include <iostream> i dodalem brakujace "" do \t.
[/edit1]
[edit2]
Zmienilem , na .. Blad przy pisaniu posta, nie w kodzie.
[/edit2]
[edit3]
Usunalem stary (wykomentowany) kod.
[/edit3]
P-149692
michal11
» 2016-07-05 14:49:13
Po co ci
C/C++
int h = millerIndexH();
int k = millerIndexK();
int l = millerIndexL();
long double d = latticeSpacing();

w funkcji latticeConstantCalculation() ? I tak to samo wczytujesz w mainie zaraz przed wywołaniem tej funkcji, przesyłaj potrzebne zmienne jako argumenty.

Swoją droga ten kod jest strasznie brzydki, większość funkcji jest bez sensu. Na przykład defineWaveLength() można skrócić tak:

C/C++
long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa\n 2 - CrKa\n 3 - FeKa\n 4 - CoKa\n 5 - MoKa\n 6 - AgKa\n 0 - other\n";
    std::cout << "Choose source: ";
    int choice;
    std::cin >> choice;
    std::cout << "\n";
   
    long double wl;
   
    switch( choice )
    {
    case 1: wl = 1.5406; break;
    case 2: wl = 2.29; break;
    case 3: wl = 1.94; break;
    case 4: wl = 1.79; break;
    case 5: wl = 0.71; break;
    case 6: wl = 0.56; break;
    case 0:
        {
            std::cout << "Input wavelength" << std::endl;
            std::cin >> wl;
        }
    }
   
    return w1;
}
P-149693
mateczek
» 2016-07-05 15:14:19
program nie uaktywnia ci się po raz drugi tylko sam zobacz
C/C++
long double latticeConstantCalculation() //calculate the constant
{
    int h = millerIndexH(); //3. ponowne pytanie o dane
    int k = millerIndexK();
    int l = millerIndexL();
    long double d = latticeSpacing();
    long double a;
    a = sqrt(( pow( h, 2 ) + pow( k, 2 ) + pow( l, 2 ) ) *( pow( d, 2 ) ) ); //proper equation
    return a;
}

int main()
{
    int h = millerIndexH(); //1. raz wywołujesz funkcję
    int k = millerIndexK();
    int l = millerIndexL();
    long double d = latticeSpacing();
    long double a = latticeConstantCalculation(); //2. teraz zobacz tutaj i skok do punktu 3
    std::cout << "(" << h << k << l << ")" << "\t" << a << "\t" << d << std::endl; //shows result
    std::ofstream o( "Lattice Parameters.txt", std::ios::app );
    o << "Miller indecies (" << h << k << l << ")/tLattice Constant " << a << "\tLattice spacing " << d << std::endl;
    std::cin.get();
}
P-149694
AterVulpes
Temat założony przez niniejszego użytkownika
» 2016-07-05 15:31:07
@michal11

Dziekuje za kod switch, tego jeszcze nie zdarzylem poznac. A wyglada, jak wyglada ;) Dopiero zaczynam.

@michal11 i mateczek

Chyba rozumiem. Dwa razy odnosze sie do w/w parametrow, wiec on chce je miec 2 razy. Ale jesli usune to z kodu, wtedy nie moge zapisac do pliku (program nie widzi h,k,l i d). Czyli musze zapisac dane do pamieci w inny sposob, zeby byly przechowywane tak, abym mogl ich uzywac w roznych czesciach programu ?

#I# zbieramDane()
#1 h
#2 k
#3 l
#4 wavelength (wl)
#5 double theta (dt)
- wszystko osobno, bo fcja zwraca tylko jedna wartosc

#II# obliczamNaPodstawieDanych()
#1 jedna funkcja na d - dane z #I#
#2 jedna funkcja na a - dane z #I# i #II#

#3 tutaj zapisuje do pliku()
musze przywolac dane z #I i #II

Czy zastosowalem zla kolejnosc?
P-149695
carlosmay
» 2016-07-05 16:08:12
Ale jesli usune to z kodu, wtedy nie moge zapisac do pliku (program nie widzi h,k,l i d). Czyli musze zapisac dane do pamieci w inny sposob, zeby byly przechowywane tak, abym mogl ich uzywac w roznych czesciach programu ?
Używaj argumentów funkcji.

I to też nie wygląda najlepiej:
C/C++
int millerIndexH()
{
    int h;
    std::cout << "Input h index" << std::endl; //input of Miller index h
    std::cin >> h;
    return h;
}

int millerIndexK()
{
    int k;
    std::cout << "Input k index" << std::endl; //input of Miller index k
    std::cin >> k;
    return k;
}

int millerIndexL()
{
    int l;
    std::cout << "Input l index" << std::endl; //input of Miller index l
    std::cin >> l;
    return l;
}
Zrób z tego jedną funkcję i użyj jej trzy razy.
P-149696
AterVulpes
Temat założony przez niniejszego użytkownika
» 2016-07-06 10:43:15
Poki co wrzucilem obliczenia do main() i usunalem kod odpowiedzialny za poszczegolne obliczenia

C/C++
int main()
{
    int h = millerIndexH();
    int k = millerIndexK();
    int l = millerIndexL();
    long double wl = defineWaveLength();
    long double t = doubleTheta();
    long double d;
    long double a;
    d =( wl /( 2 * sin( t ) ) );
    a = sqrt(( pow( h, 2 ) + pow( k, 2 ) + pow( l, 2 ) ) *( pow( d, 2 ) ) );
    std::cout << "(" << h << k << l << ")" << "\t" << a << "\t" << d << std::endl; //shows result
    std::ofstream o( "Lattice Parameters.txt", std::ios::app ); //create txt file with name and append
    o << "(" << h << k << l << ")\tLattice Constant a=" << a << "\tLattice spacing d_hkl" << d << std::endl; //saves results to a file
    std::cin.ignore();
    std::cin.clear();
    std::cin.get();
}

Teraz wszystko dziala, ale nie wiem czy to dobra praktyka. Uzycie & nic nie dalo, czyli zle go uzywam. Bede wiec szukal jakiegos poradnika lopatologicznego, jak przenosci wartosci f-cji do innej fcji, zeby calosc byla bardziej modularna (zbieranie danych w jednym miejscu, obliczenia w drugim, zapisywanie w trzecim).

@carlosmay

Masz na mysli cos takiego ?
C/C++
int millerIndecies()
{
    int m_i;
    int count = 1;
    while( count <= 3 )
    {
        std::cout << "Enter Miller Indecies" << std::endl;
        std::cin >> m_i;
        ++count;
    }
    return m_i;
}
To by bylo fajne, gdybym wiedzial jak rozdzielic potem wprowadzone dane (musza byc wprowadzone do rownania w scisle okreslonej kolejnosci).
P-149711
michal11
» 2016-07-06 10:53:36
Na przykład:
C/C++
int millerIndex( char name )
{
    int ret;
    std::cout << "Input " << name << " index" << std::endl; //input of Miller index h
    std::cin >> ret;
    return ret;
}

int main()
{
   
    int h = millerIndex( 'h' );
    int k = millerIndex( 'k' );
    int l = millerIndex( 'l' );
   
    return 0;
}


A jeżeli chcesz mieć tylko jedną funkcje do wpisywania tych indeksów to zwracaj z niej tablicę z wczytanymi wartościami.
P-149713
AterVulpes
Temat założony przez niniejszego użytkownika
» 2016-07-06 11:18:40
@michal11

Dziekuje za przyklad przypisania zmiennych hkl do name (ilosc wywolac (int) w main(), daje ilosc pytan w millerIndex())

Tablica = Array ?
P-149717
« 1 » 2
  Strona 1 z 2 Następna strona