Array aus Zeichenketten



  • Moin, moin

    ich bin noch relativer C-Newbie und habe unter LInux in C ein Problem mit Arrays aus Zeichenketten und zwar im folgendem Zusammenhang:

    In meinem Programm möchte ich die Namen von Musik-Dateien eines bestimmten Verzeichnisses sortiert in eine Datei schreiben (Playlist erstellen).
    Ablauf des Programms:
    1. Zählen der vorhandenen Musik-Dateien im bestimmten Verzeichnis
    2. Zeichenketten-Array in Abhängigkeit der gezählten Dateien mit malloc erstellen
    3. File-Namen in Array eintragen
    4. Array nach Datei-Namen sortieren
    5. Anlegen einer m3u-Datei
    6. Schreiben des sortierten Arrays in diese m3u-Datei
    7. Ende

    Bis zum Punkt 4 scheint alles auch reibungslos zu funktionieren, wenn ich aber die m3u-Datei anlege, werden in meinem Array mehrere Einträge verstümmelt. Im Moment denke ich, dass ich einen Fehler mit malloc() mache, habe dazu auch schon wie wild gegoogelt und bin jetzt total hilflos.

    Kann mir jemand Bitte sagen, was ich falsch mache?

    meine malloc() Anweisung

    // memory allokation of filenamesArrayDirectory1
        filenamesArrayDirectory1 =  malloc (countedFilesDirectory1 * sizeof(char *));
        if (filenamesArrayDirectory1 == NULL)
        {   fprintf(stderr, "malloc() failed\n");
    	 	_exit(1);
        }
        for(i=0;i<countedFilesDirectory1;i++)
        {   filenamesArrayDirectory1[i] = malloc (sizeof(char) * FILENAMELENGTH);
            if (filenamesArrayDirectory1[i] == NULL)
    	{   fprintf(stderr, "malloc() failed\n");
    	    _exit(1);
    	}
        }
    

    Danke

    hagenb



  • hagenb schrieb:

    Kann mir jemand Bitte sagen, was ich falsch mache?

    Nicht, solange du nicht deinen Code zeigst.

    Edit: Warst schnelle. Aber in dem Code ist kein Fehler. Ich denke, dass du später einen Fehler machst. Oder die Variable FILENAMELENGTH ist falsch. Aber das kann man nur raten.



  • Tschuldigung, hab beim ersten Mal glatt den Code vergessen 😕 , habe ihn reineditiert



  • Wenn das mit malloc() doch so stimmt, würde ich dann zur großkalibrigen Waffe greifen und einfach den ganzen code posten, hoffentlich sind 130 Zeilen nicht zu viel 😕

    #include <unistd.h>
    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 127
    
    int compare (const void *arg1, const void *arg2);
    
    char **filenamesArrayDirectory1;
    FILE *allFilesDirectory1;
    char *directory1 = "/home/hagen/directory1/";
    char *directoryHome = "/home/hagen";
    char *filenameForDirectory1 = "playlist1.m3u";
    int countedFilesDirectory1 = 0;
    
    int main()
    {
    	int i, returnValue = 0;
    
    	// count files in directory1
        DIR *dp1;
        struct dirent *entry1;
        struct stat filestatus1;
        if ((dp1=opendir(directory1))==NULL)
        {   fprintf(stderr, "\ncannot open directory: %s\n", directory1);
            return -1;
        }
        chdir(directory1);
        while((entry1=readdir(dp1)) != NULL)
        {   lstat(entry1->d_name, &filestatus1);
            if(S_ISREG(filestatus1.st_mode))
    	{   countedFilesDirectory1++;
    	}
        }
        chdir("..");
        closedir(dp1);
    
        // memory allokation of filenamesArrayDirectory1
        filenamesArrayDirectory1 =  malloc (countedFilesDirectory1 * sizeof(char *));
        if (filenamesArrayDirectory1 == NULL)
        {   fprintf(stderr, "malloc() failed\n");
    	 	_exit(1);
        }
        for(i=0;i<countedFilesDirectory1;i++)
        {   filenamesArrayDirectory1[i] = malloc (sizeof(char) * FILENAMELENGTH);
            if (filenamesArrayDirectory1[i] == NULL)
    	{   fprintf(stderr, "malloc() failed\n");
    	    _exit(1);
    	}
        }
    
    	// write filenamesArrayDirectory1 with filenames
        if ((dp1=opendir(directory1))==NULL)
        {   fprintf(stderr, "\ncannot open directory: %s\n", directory1);
            return -1;
        }
        chdir(directory1);
        i=0;
        while((entry1=readdir(dp1)) != NULL)
        {   lstat(entry1->d_name, &filestatus1);
            if(S_ISREG(filestatus1.st_mode))
    	{   filenamesArrayDirectory1[i] = entry1->d_name;
    	    i++;
    	}
        }
        chdir("..");
        closedir(dp1);
    
    	// print out current array
    	for (i=0; i<countedFilesDirectory1; i++)
    	{   printf("\n%s", filenamesArrayDirectory1[i]);						     
    	}
    	printf("\n\n");
    
        // sort entries in filenamesArrayDirectory1 
        qsort ((void*) filenamesArrayDirectory1 , (size_t) countedFilesDirectory1, sizeof (char*), compare);
    
    	// print out current array
    	for (i=0; i<countedFilesDirectory1; i++)
    	{   printf("\n%s", filenamesArrayDirectory1[i]);						     
    	}
    	printf("\n\n");
    
    	// open file allFilesDirectory1
        chdir(directoryHome);
        allFilesDirectory1 = fopen(filenameForDirectory1, "w");
        if(allFilesDirectory1 == NULL)
        {   fprintf(stderr, "\ncannot open %s\n", filenameForDirectory1);
    	return -1;
        }
    
        // write sorted filenames in allFilesDirectory1
        if ( countedFilesDirectory1 > 0 )
        {  	for (i=0; i<countedFilesDirectory1; i++)
    		{   returnValue = fprintf( allFilesDirectory1, "%s%s\n",  directory1, filenamesArrayDirectory1[i]);
    	     	if(returnValue == EOF)
    	     	{ 	fprintf(stderr, "\nFehler fprintf mit index %i", i); 
    				exit(EXIT_FAILURE);
    	     	}
    		}
        }
    
        // close allFilesDirectory1
        fflush(allFilesDirectory1);
        returnValue = fclose(allFilesDirectory1);
        if ( returnValue != 0 )
        { 	fprintf(stderr, "\nFehler fclose allFilesDirectory1 - Fehlercode fclose: %i", returnValue);
        }
    
    	// print out current array
    	for (i=0; i<countedFilesDirectory1; i++)
    	{   printf("\n%s", filenamesArrayDirectory1[i]);						     
    	}
    	printf("\n\n");
    
    	return 0;
    
    }
    
    int compare( const void *pszS1, const void *pszS2)
    {    return (strcmp( *(char **)pszS1, *(char **)pszS2));
    }
    

    Demjenigen der mir sagt was und wie ich falsch mache, wird mein Dank bis in alle Zeiten nacheilen.



  • In Zeile 68 machst du einen typischen Anfängerfehler:

    Hier weißt du deinem StringArray filenamesArrayDirectory1 an
    Position i nicht den String sondern die Adresse von entry1->d_name.

    Richtig wäre:

    while((entry1=readdir(dp1)) != NULL) {
            lstat(entry1->d_name, &filestatus1);
            if(S_ISREG(filestatus1.st_mode)) memcpy(filenamesArrayDirectory1[i++], entry1->d_name, strlen(entry1->d_name));
        }
    

    Gruß mcr



  • @ mcr

    Vielen Dank, natürlich hast du vollkommen Recht. Ich kann mir im Moment auch nicht mehr erklären was da für ein Blödsinn programmiert habe. Ich hatte mich so auf das malloc() eingeschossen, das ich den Rest gar nicht mehr richtig kontrolliert habe. Zur Strafe werde ich mir das Kapitel über Zeiger nochmals reinhelfen.

    Das Programm funzt wunderbar jetzt, ich musste nur noch strlen()+1 rechnen um die Null-Terminierung mitzukopieren.

    hagenb


Anmelden zum Antworten