Speicherzugriffsfehler bei strncpy



  • Hi(gh)!

    Eigentlich eine ganz einfache Aufgabe: aus dem Verzeichnisnamen "04479_hist" sollen die ersten fünf Zeichen extrahiert und in einem neuen char-Array gespeichert werden.

    Hier ist der Code:

    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    
    int main(void)
    {
      DIR *dir;
      dirent *entry;
      char *name;
      char *number;
      char stationen[1213][2][50];
      unsigned short i=0;
      const char *path="/home/Verschiedenes/Klima/Rohdaten/Deutschland (DWD)/Tageswerte/";
      
      dir = opendir(path);
      while (dir)
      {  
        entry = readdir(dir);
        if (!entry) break;
        name = entry->d_name;
        if (strlen(name) == 10)
        {  
          strcpy(stationen[i][0], name);
          i++;
        }
      }
      for (i = 0; i < 1 /*1213*/; i++)
      {  
        printf("Ermittle Ortsname zu Stations-Nummer %s\n", stationen[i][0]);
        number = strncpy(number, stationen[i][0], 5);
        // printf("Nummer: %s\n", number);
        
      }  
    }
    

    Kompiliert wird es anstandslos, aber die letzte Zeile (also number = strncpy(number, stationen[i][0], 5)) produziert einen Speicherzugriffsfehler zur Laufzeit! Warum?

    Bis bald im Khyberspace!

    Yadgar



  • @Yadgar sagte in Speicherzugriffsfehler bei strncpy:

    char *number;

    Wieviele Bytes kannst du da reinkopieren?


  • Mod

    number zeigt auf nix.

    Es sieht so aus, als ob du hier die Aufgabe eines relativ trivialen Shellscripts umständlich und schlecht in C programmieren würdest. Deine Zeit ist vermutlich besser investiert darin, Shellscripte zu lernen anstatt C zu lernen (und du musst noch viel über C lernen).

    PS: Ich sehe, das gleiche hat man dir schon in vorhergehenden Thread gesagt, aber es war dir offensichtlich egal. Tja, dann sitzt man halt einen Monat an etwas, was man in einer Stunde ohne Vorwissen hätte schaffen können.



  • Hi(gh)!

    Es sieht so aus, als ob du hier die Aufgabe eines relativ trivialen Shellscripts umständlich und schlecht in C programmieren würdest. Deine Zeit ist vermutlich besser investiert darin, Shellscripte zu lernen anstatt C zu lernen (und du musst noch viel über C lernen).

    Ich könnte viel weiter sein, wenn ich mich jeden Tag mehrere Stunden mit Programmieren (in meinem Fall: C, C++ und PHP/MySQL) beschäftigen würde... aber meine Persönlichkeitsstruktur gibt das leider nicht her!

    Ich will alles und schaffe nichts...

    Bis bald im Khyberspace!

    Yadgar



  • Hi(gh)!

    @SeppJ sagte in Speicherzugriffsfehler bei strncpy:

    number zeigt auf nix.

    Also initialisiere ich number mit einem Leerstring:

    char number[1]="";
    

    ...und das kompiliert dann nicht einmal mehr, sondern schmeißt einen Error:

    dwdread.c: In function ‘int main()’:
    dwdread.c:30:12: error: incompatible types in assignment of ‘char*’ to ‘char [1]’
    number = strncpy(number, stationen[i][0], 5);

    Und jetzt? Nein, ich will kein Shellscript schreiben, weil diese Funktion hier nur ein winziger Teil eines viel größeren Programms sein soll, das Wetter-Messdaten aus ASCII-Texten ausliest, Durchschnittts-, Minimal- und Maximalwerte (und noch einiges Andere) berechnet und diese dann in Wikipedia-tauglichen Klimatabellen einsortiert...

    Bis bald im Khyberspace!

    Yadgar



  • @Yadgar sagte in Speicherzugriffsfehler bei strncpy:

    Also initialisiere ich number mit einem Leerstring

    Warum? Du brauchst keinen Leerstring sondern Platz. Ein Byte reicht wohl eher nicht.

    number = strncpy(number, stationen[i][0], 5); die Zuweisung ist doch völlig überflüssig.

    No null-character is implicitly appended at the end of destination if source is longer than num. Thus, in this case, destination shall not be considered a null terminated C string (reading it as such would overflow).

    Ist der String bei dir immer Nullterminiert?



  • @Yadgar sagte in Speicherzugriffsfehler bei strncpy:

    aus dem Verzeichnisnamen "04479_hist" sollen die ersten fünf Zeichen extrahiert und in einem neuen char-Array gespeichert werden.

    Brauchst du die Zeichen oder den Wert der Zahl?

    Strings funktionieren in C anders, als in fast jeder anderen Programmiersprache.
    Da ist nichts mit Zuweisung oder dynamischer Längenänderung.



  • Hi(gh)!

    @DirkB sagte in Speicherzugriffsfehler bei strncpy:

    @Yadgar sagte in Speicherzugriffsfehler bei strncpy:

    aus dem Verzeichnisnamen "04479_hist" sollen die ersten fünf Zeichen extrahiert und in einem neuen char-Array gespeichert werden.

    Brauchst du die Zeichen oder den Wert der Zahl?

    Strings funktionieren in C anders, als in fast jeder anderen Programmiersprache.
    Da ist nichts mit Zuweisung oder dynamischer Längenänderung.

    An sich weiß ich das... aber nicht kurz nach dem Aufstehen und ohne Kaffee! Oder genauer: nicht, wenn ich nur alle paar Jahre mal was in C mache (und mir ansonsten C++ in den Knochen steckt - da ist es ja easy mit den Strings)... anscheinend bin ich höchstens zwei Stunden am Tag in der Lage, halbwegs fehlerfrei zu programmieren, ansonsten macht mir meine Gehirnchemie einen Strich durch die Rechnung, entweder unterkoffeiniert oder Suppenkoma... ich nehme wahrscheinlich die falschen Drogen!

    Bis bald im Khyberspace!

    Yadgar



  • Hi(gh)!

    @manni66 sagte in [Speicherzugriffsfehler bei strncpy](/forum

    Ist der String bei dir immer Nullterminiert?

    Weiß ich nicht, daher habe ich zur Sicherheit noch "manuell" ein '\0' ans Ende gehängt!

    Bis bald im Khyberspace!

    Yadgar


  • Mod

    @Yadgar sagte in Speicherzugriffsfehler bei strncpy:

    Hi(gh)!

    @manni66 sagte in [Speicherzugriffsfehler bei strncpy](/forum

    Ist der String bei dir immer Nullterminiert?

    Weiß ich nicht, daher habe ich zur Sicherheit noch "manuell" ein '\0' ans Ende gehängt!

    Musst du aber! C vergibt kein Halbwissen. Du musst in C zwei Dinge immer wissen:

    1. Du musst bezüglich des Quellcodes von jedem einzelnen Zeichen in deinem Programm genau wissen, wo und warum du es setzt.
    2. Du musst bezüglich des Programmablaufs zu jeder Stelle genau wissen, in welchem Zustand eine Variable ist.

    Sonst hagelt es Abstürze wie hier. Wenn du Glück hast. Wenn du Pech hast, passiert wer weiß was und du bemerkst den Fehler nicht einmal.

    PS: Nochmals: Wie man mit zwei bis 3 Zeilen einer beliebigen Shellscripsprache bestimmte Teile aus einer Reihe Dateinamen extrahiert, kannst du heute Nachmittag noch lernen und selber programmieren, selbst wenn du das noch nie zuvor gemacht hast. In C wird es dir heute Nachmittag wahrscheinlich auch noch jemand für diesen einen speziellen Fall vormachen, aber du wirst die Lösung nicht verstehen und bist beim nächsten Schritt wieder hier mit fast der gleichen Frage.



  • @SeppJ sagte in Speicherzugriffsfehler bei strncpy:

    In C wird es dir heute Nachmittag wahrscheinlich auch noch jemand für diesen einen speziellen Fall vormachen

    https://onlinegdb.com/VeOa6Wcl6



  • @SeppJ sagte in Speicherzugriffsfehler bei strncpy:

    Musst du aber! C vergibt kein Halbwissen. Du musst in C zwei Dinge immer wissen:

    1. Du musst bezüglich des Quellcodes von jedem einzelnen Zeichen in deinem Programm genau wissen, wo und warum du es setzt.
    2. Du musst bezüglich des Programmablaufs zu jeder Stelle genau wissen, in welchem Zustand eine Variable ist.

    Sonst hagelt es Abstürze wie hier. Wenn du Glück hast. Wenn du Pech hast, passiert wer weiß was und du bemerkst den Fehler nicht einmal.

    PS: Nochmals: Wie man mit zwei bis 3 Zeilen einer beliebigen Shellscripsprache bestimmte Teile aus einer Reihe Dateinamen extrahiert, kannst du heute Nachmittag noch lernen und selber programmieren, selbst wenn du das noch nie zuvor gemacht hast. In C wird es dir heute Nachmittag wahrscheinlich auch noch jemand für diesen einen speziellen Fall vormachen, aber du wirst die Lösung nicht verstehen und bist beim nächsten Schritt wieder hier mit fast der gleichen Frage.

    Dann ist Programmieren eben nichts für mich! Wie auch so ziemlich das ganze übrige Leben nichts für mich ist - ein kleines Beispiel: seit bald 30 Jahren wohne ich in einer eigenen Wohnung, und doch habe ich bis heute null Routine in Hausarbeit, ich schaffe das alles immer nur mehr schlecht als recht, und es dauert dreimal solange wie bei normalen Menschen!

    Mein Fazit: nimm mich mit, grauer Bus, nach Hadamar!


  • Mod

    Naja, andere Sprachen sind halt vergebender als C. Natürlich muss man halbwegs wissen, was man tut, aber die wenigsten Sprachen explodieren einem direkt ins Gesicht, wenn man versucht ein paar Strings zu manipulieren, ohne vorher 10 Seiten Erklärung genau gelesen und verstanden zu haben. Und bei den vermeintlich einfacheren Sprachen funktionieren auch Intuitionen, wie z.B. das string1 + string2 so etwas sein könnte wie die Aneinanderreihung der beiden Strings (Ist es in C nicht, falls du es nicht wusstest). Da kann man dann einfach ein bisschen rumprobieren und wurschteln, bis es passend aussieht. Das geht bei großen Sachen natürlich immer noch schief, aber für so kleine Scripte reicht es meistens.


Anmelden zum Antworten