10 svar
348 visningar
shiela behöver inte mer hjälp
shiela 23 – Fd. Medlem
Postad: 17 aug 2020 09:09

Felmeddelande "Segmentation Fault" pga värdet försöker ändras utanför array

Hej, 

När jag kör detta program så får jag felmeddelandet "segmentation fult" eftersom ett värde försöker andras utanför arrayen "histogram_abs" i funktionen "berakna_histogram_abs()". Jag har stirrat mig blind på koden och behöver hjälp! Jag fick feedback från en assistent som rättade min uppgift och assistenten sa: "Kolla på vilka index du försöker uppdatera histogram_abs i funktionen berakna_histogram_abs."

Någon som har en idé på hur man åtgärdar detta felmeddelande? Se kod nedan. 

Tacksam för svar!

 

 

#include <string>

 #include <cctype>

 #include <iostream>

 #include <fstream>

 #include <cmath>

 using namespace std;

 


 // Globala konstanter:

 


 // Tips: Anv‰nd de globala konstanterna ANTAL_BOKSTAVER och ANTAL_SPRAK

 // ist‰llet fˆr v‰rdena 26 och 4 i programmet.

 const int ANTAL_BOKSTAVER = 26;  //A-Z

 const int ANTAL_SPRAK = 4;

 


 // 2d-arrayen TOLK_HJALP innehÂller bokstavsfrekvensen i %

 // fˆr fyra sprÂk. TOLK_HJALP[0][0] ‰r frekvensen av

 // bokstaven a fˆr engelska.TOLK_HJALP[0][25] ‰r frekvensen av

 // bokstaven z fˆr engelska.

 // Arrayen ‰r en GLOBAL KONSTANT och skall allts ej skickas

 // som parameter till den funktion som behˆver den.

 const double TOLK_HJALP[ANTAL_SPRAK][ANTAL_BOKSTAVER]=

        {{8.27,1.48,2.94,4.03,11.78,2.22,1.72,6.77, //engelska

          7.39,0.12,0.81,3.76,2.85,6.71,7.79,1.54,

          0.05,5.95,6.69,9.07,2.66,1.13,2.14,0.19,

          1.89,0.03},

         {7.97,1.40,3.55,3.79,16.89,1.02,1.00,0.75, //franska

          7.08,0.38,0.04,5.51,2.82,8.11,5.19,2.78,

          1.01,6.69,8.35,7.22,6.09,1.35,0.02,0.54,

          0.30,0.15},

         {9.50,1.11,1.53,5.30,8.94,1.74,3.57,3.94,  //svenska

          3.98,0.89,3.26,4.93,3.41,8.46,5.01,1.77,

          0.00,6.73,5.56,9.20,1.94,2.42,0.00,0.05,

          0.45,0.00},

         {5.12,1.95,3.57,5.07,16.87,1.35,3.00,5.79, //tyska

          8.63,0.19,1.14,3.68,3.12,10.64,1.74,0.42,

          0.01,6.30,6.99,5.19,3.92,0.77,1.79,0.01,

          0.69,1.24}};

 


 // Globala variabler ‰r ej tillÂtna

 


 //--------------------------------------------------------

 // H‰r kommer klassdeklarationen

 class Text

 {

 private:                                     //Attribut

     string text;                            //Textsträng för analys

     int histogram_abs[ANTAL_BOKSTAVER];     //Array, innehåller absoluta histogrammet, längen är 26

     double histogram_rel[ANTAL_BOKSTAVER];     //Array, innehåller relativa histogrmmet

     int antal;                              //Attribut som håller reda på antal bokstäver i histogrammet

     

 public:                                 //Metoder

     Text();                             //Standardkonstruktor

     

 


     void set_text(string ny_text);      //Metod (funktion) som sätter värdet på textsträngen i klassen

     bool berakna_histogram_abs();        //Beräknar ett bokstavshistogram av texten, dvs antal bokstäver i histogrammet

     void skriv_histogram_abs();          //Skriver ut bokstavshistogrammet

     void abs_till_rel();                    //Metod som beräknar relativt histogram

     void plotta_histogram_rel();        //Metod som plottar relativa histogrammet med * (en procent är två symboler)

     void berakna_histogram();           //Gör inga nya beräkningar av histogrammet, men ska anropa berakna_histogram_abs() och abs_till_rel(). Det absoluta beräknas först och sedan det relativa histogrammet. Det relativa histogrammet ska bara beräknas om det absoluta histogrammet innehåller bokstäver.

     string tolka();     //Metoden jämför beräknat relativt histogram med fyra fördefinerade språkhistogram

 };

 


     string namn_pa_fil(string namn);

     string inlasning(const string& namn);

 // -------------------------------------------------------

 


 // Huvudprogram:

 


 int main()

 {

  // Deklarera variabler

   string text;

   string filnamn;

   bool hist_OK;

   Text min_text;  // Ett objekt av typen Text skapas

 


   filnamn = namn_pa_fil(filnamn);

   text = inlasning(filnamn);

   min_text.set_text( text );          //Skickar strängen 'text' till objektet minText

 


   // Ber‰kna och skriv ut histogrammet

   //hist_OK = min_text.berakna_histogram_abs( );

   //min_text.abs_till_rel();

   min_text.berakna_histogram();

   min_text.skriv_histogram_abs( );

   min_text.plotta_histogram_rel();

   min_text.tolka();

   return 0;

 }

 


 // -------------------------------------------------------

 // H‰r skriver du klassimplementationen

 


 Text::Text()                          //Skapar och nollställer standardkonstruktorn

 {

    text="";

 


    for(int i=0; i<ANTAL_BOKSTAVER; i++)

    {

        histogram_abs[i]=0;

    }

 


    antal=0;

 }

 


 void Text::set_text(string ny_text)           //Tilldelar variabeln text ett värde

 {

    text = ny_text;

 }

 

 

 

 bool Text::berakna_histogram_abs()            //Beräknar förekomst av olika bokstäver

 {

 


    for (int i=0; i<ANTAL_BOKSTAVER; i++)

    {

        histogram_abs[i] = 0;                 //Nollställer frekvensen

    }

 

 

 

    antal=0;

     

    for(unsigned int i = 0; i<text.length(); i++)

    {

        char temp = text[i];

            if(isalpha(temp))               //Om tecknet är en bokstav så vill vi öka med 1

            antal++;

 


            if(isupper(text[i]))            //Om bokstaven är en stor bokstav så ändras den till en liten

            temp=tolower(temp);

            histogram_abs[(temp - 'a')]++;   // frekvensräknaren för den valda bokstaven ökas med 1

    }

 


    if(antal==0)                            //Om antalet bokstäver är noll så ges boolen värdet false, annars är den true

        return false;

    else

        return true;

 }

 


 void Text::skriv_histogram_abs()

 {

     cout << "\nResultat för bokstäverna A-Z " << endl;

     cout << "\nTotala tecken i texten: " << text.size() << endl;

     cout <<"\nBokstav:\tFrekvens:\n";

 


    for (int i=0; i<ANTAL_BOKSTAVER; i++)

    {

        char Bokstav = char (i+'A');

        if (histogram_abs[i])

            cout << Bokstav << "        \t" << histogram_abs[i] <<endl;

 


        else

            cout << Bokstav << "               0" << endl;

    }

 }

 


 void Text::abs_till_rel()

 {

    for (int i=0; i<ANTAL_BOKSTAVER; i++)

    {

        histogram_rel[i] = (float(histogram_abs[i]))/(float(antal))*100;

                                                                

    }

 }

 


 void Text::plotta_histogram_rel()

 {

     char bokstav;

     cout << "\nBokstav:\tRelativ frekvens:\n";

     for (int i = 0; i < ANTAL_BOKSTAVER; i++)

     {

         double k = 0.5;

         bokstav = 'A' + i;

         cout << bokstav << ": ";

 


         while (k < histogram_rel[i])

         {

             cout << "*";

             k += 0.5;

         }

         cout << endl;

     }

 }

 

 

 

 


 void Text::berakna_histogram()

 {

    bool histOK=Text::berakna_histogram_abs();

    if (histOK)

    {

        Text::abs_till_rel();

    }

    else

        cout << "Texten innehåller inga bokstäver.";

 


 }

 


 string Text::tolka()

 {

   double minst_skillnad;

    int minst_index;

    string sprak[ANTAL_SPRAK]={"engelska", "franska", "svenska", "tyska"};

    double skillnad = 0.0;

    double summa[ANTAL_SPRAK]={0.0, 0.0, 0.0, 0.0};

 


    for(int j=0; j<ANTAL_SPRAK; j++)

    {

        for(int i=0; i<ANTAL_BOKSTAVER; i++)

        {

            skillnad = (TOLK_HJALP[j][i] - histogram_rel[i]);

            summa[j] = summa[j]+(skillnad*skillnad);

        }

 

 

 

        minst_skillnad = summa[j];

        minst_index = j;

        for(int k=0; k<ANTAL_SPRAK; k++ )

        {

            if(summa[k]<minst_skillnad)

            {

                minst_skillnad = summa[k];

                minst_index = k;

            }

        }

    }

     cout << "Engelska har kvadratsumman: " << summa[0] << endl;

     cout << "Franska har kvadratsumman: " << summa[1] << endl;

     cout << "Svenska har kvadratsumman: " << summa[2] << endl;

     cout << "Tyska har kvadratsumman: " << summa[3] << endl;

    cout << "Det är mest troligt att texten är skriven på: " << sprak[minst_index] << endl;

    return 0;

 }

 


 //--------------------------------------------------------

 // Funktionsdefinitioner:

 


 string namn_pa_fil(string filnamn)

 {

     cout << "Vad heter filen du vill testa?: " << endl;

     getline(cin, filnamn);

 


     if (filnamn.rfind(".txt") == string::npos)

     {

         filnamn.append(".txt");

     }

     return filnamn;

 }

 

 

 

 string inlasning(const string& filnamn)

 {

     string tmpString;

     string returneradText;

     ifstream fin(filnamn.c_str());

 


     if (!fin)

     {

         cout << "Det finns ingen fil med namnnet " << filnamn << endl;

         exit(EXIT_FAILURE);

     }

     else

     {

         while (getline(fin, tmpString))

         {

             returneradText += tmpString;

         }

     }

     return returneradText;

 }

haraldfreij 1322
Postad: 17 aug 2020 09:55

Du verkar uppdatera histogrammet även om det inte är en bokstav du får in. Vad händer då?

Laguna Online 30635
Postad: 17 aug 2020 09:57

Vi behöver se indata också för att se varför det blir fel, men använd assistentens tips och skriv ut värdet av temp-'a' precis innan du använder det som index, så får du se om det blir ett olämpligt värde.

Aerius 504 – Fd. Medlem
Postad: 17 aug 2020 09:58

Gör utskrifter för att titta vad variablerna har för värde där felet uppstår.

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 09:59
haraldfreij skrev:

Du verkar uppdatera histogrammet även om det inte är en bokstav du får in. Vad händer då?

Man kan utgå från att endast bokstäver läses in, dvs man behöver endast hantera input/inläsning av bokstäverna A-Z (a-z). Det är ju iaf skönt att ej felhantering krävs för uppgiften! :)

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 10:01 Redigerad: 17 aug 2020 10:04
Laguna skrev:

Vi behöver se indata också för att se varför det blir fel, men använd assistentens tips och skriv ut värdet av temp-'a' precis innan du använder det som index, så får du se om det blir ett olämpligt värde.

Indata är bl.a en textfil som innehåller följande text:

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

 

Men det kan också vara en textfil som innehåller en lååååång text skriven på engelska, tyska, svenska eller franska och så avgör programmet vilket text den är skriven på. Men när jag testkör programmet så använder jag textfilen med bara det som står ovan. 

 

Tror du att du kan kolla på hur det ser ut om du har denna rad som input? Problemet är att jag inte får ett felmeddelande, utan det är assistenten som får det när han kör koden. Så jag har jättesvårt att hitta felet själv!

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

Laguna Online 30635
Postad: 17 aug 2020 10:09

Om assistenten får felet men inte du så måste ni reda ut vad ni gör olika. Tittar du på när assistenten kör?

Gör det jag föreslog och låt assistenten köra igen.

En sak som är fel är i alla fall att du hanterar alla tecken på samma sätt, även sådana som inte är bokstäver. Vad blir temp-'a' då?

Aerius 504 – Fd. Medlem
Postad: 17 aug 2020 11:37
shiela skrev:
Laguna skrev:

Vi behöver se indata också för att se varför det blir fel, men använd assistentens tips och skriv ut värdet av temp-'a' precis innan du använder det som index, så får du se om det blir ett olämpligt värde.

Indata är bl.a en textfil som innehåller följande text:

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

 

Men det kan också vara en textfil som innehåller en lååååång text skriven på engelska, tyska, svenska eller franska och så avgör programmet vilket text den är skriven på. Men när jag testkör programmet så använder jag textfilen med bara det som står ovan. 

 

Tror du att du kan kolla på hur det ser ut om du har denna rad som input? Problemet är att jag inte får ett felmeddelande, utan det är assistenten som får det när han kör koden. Så jag har jättesvårt att hitta felet själv!

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

Det fetade. Om assistenten får fel men inte du då kör ni olika program. Skicka ditt program till assistenten som fungerar så löser det sig. Jag tror du rättat felet omedvetet i din kod. Om din kod bara får bokstäver som input då ser jag inga fel (, så klart positivt att skriva en if-sats så det bara lagras bokstäver i histogrammet ändå. Veta att input data är rätt till en viss funktion är sällan fel), kan absolut vara så att assistenten har en text som innehåller något tecken som inte är en bokstav.

shiela 23 – Fd. Medlem
Postad: 18 aug 2020 11:46
Aerius skrev:
shiela skrev:
Laguna skrev:

Vi behöver se indata också för att se varför det blir fel, men använd assistentens tips och skriv ut värdet av temp-'a' precis innan du använder det som index, så får du se om det blir ett olämpligt värde.

Indata är bl.a en textfil som innehåller följande text:

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

 

Men det kan också vara en textfil som innehåller en lååååång text skriven på engelska, tyska, svenska eller franska och så avgör programmet vilket text den är skriven på. Men när jag testkör programmet så använder jag textfilen med bara det som står ovan. 

 

Tror du att du kan kolla på hur det ser ut om du har denna rad som input? Problemet är att jag inte får ett felmeddelande, utan det är assistenten som får det när han kör koden. Så jag har jättesvårt att hitta felet själv!

"aBbCcCDDDDEEeFFGhhiiiJJJJKkkLLmMnooPpPQQQQRRrSSTuuVVvWwWwXXxyyyZ"

Det fetade. Om assistenten får fel men inte du då kör ni olika program. Skicka ditt program till assistenten som fungerar så löser det sig. Jag tror du rättat felet omedvetet i din kod. Om din kod bara får bokstäver som input då ser jag inga fel (, så klart positivt att skriva en if-sats så det bara lagras bokstäver i histogrammet ändå. Veta att input data är rätt till en viss funktion är sällan fel), kan absolut vara så att assistenten har en text som innehåller något tecken som inte är en bokstav.

Tack för hjälpen! Jag tror att jag vet vad jag gjorde för fel... (Jag hade inte koll på att filen man läser in ska ligga i Debugging mappen när man kör i Xcode, så får nog ta nya tag med uppgiften och kolla vad det är frågan om nu när jag vet detta)

Aerius 504 – Fd. Medlem
Postad: 18 aug 2020 20:40

i funktionsdefinitionen

bool Text::berakna_histogram_abs()

under

for(unsigned int i =0; i<text.length(); i++)

finns en if-sats

if(isalpha(temp))

denna if-sats ger möjligheten att den som skrivit programmet tänkt sig att det ibland inte kommer en bokstav. Sätt måsvingar runt det som är under denna if-sats så du är säker på att histogram_abs[(temp - 'a')]++ bara uppdateras med bokstäver.

shiela 23 – Fd. Medlem
Postad: 18 aug 2020 20:55
Aerius skrev:

i funktionsdefinitionen

bool Text::berakna_histogram_abs()

under

for(unsigned int i =0; i<text.length(); i++)

finns en if-sats

if(isalpha(temp))

denna if-sats ger möjligheten att den som skrivit programmet tänkt sig att det ibland inte kommer en bokstav. Sätt måsvingar runt det som är under denna if-sats så du är säker på att histogram_abs[(temp - 'a')]++ bara uppdateras med bokstäver.

Tack så mycket!! 

Svara
Close