Hilfe bei C-Prigramm mit Zeilenweise einlesen und sortieren



  • Hallo!

    Ich habe eine "kleine" Schwäche in c und jetzt müssen wir eine Aufgabe machen, mit der ich gar nicht klar komme..

    **
    Aufgabenstellung:
    Schreiben Sie ein Programm, dass eine Datei zeilenweise einliest und die Zeilen in einem Feld von Strings speichert. Die Datei soll maximal 1000 Zeilen enthalten und jede Zeile soll maximal 300 Zeichen enthalten. Der Name der Datei wird dem Programm als Argument in der Kommandozeile übergeben. Verwenden Sie zur Speicherung einer eingelesenen Textzeile die Standard-C-Funktion

    #include <string.h>
    char *strdup(char *s)

    Diese Funktion legt ein Duplikat des Strings s im Speicher an (und reserviert dafür automatisch Speicher) und gibt die Stelle des Duplikates als Zeiger zurück.
    Die so eingelesenen Zeilen sollen anschließend sortiert werden. Schreiben Sie dafür eine Funktion

    void str_sort(char *l[], int n)

    Sie sortiert das Feld der Strings l (mit n Elementen) mit Hilfe der in Aufgabe 1 erstellten Funktion str_sompare().
    Zum Abschluss sollen die so sortierten Zeilen am Bildschirm ausgegeben werden.**

    Quellcode (bisher):

    #include <stdio.h>
    #include <string.h>
    #include "str_compare.h"
    char *strdup(char *s)
    
    int readNumberFile(char*filename)
    {
       int i=0;
       char line[300];
    
       FILE* open = fopen(filename,"r");
    
       while (!feof(open) && (i<1000))
       { 
          fscanf(open,"%s",line);
          s[i]=line;
          i++
       }
       fclose(open);
       return i;
    }
    char *strdup(char *s)
    {
    }
    void str_sort(char *l[], int n)
    {
    }
    int main(int argc, char* argv)
    {
       long int v[1000];
    
       return -1;
    }
    

    das erste Programm ist folgendes:(str_compare.c)

    #include <stdio.h>
    #include "str_compare.h"
    #define MAX 20
    
    /*int str_compare( char *s1, char *s2);
    
    int main()
    {
       char s1[MAX], s2[MAX];
       int suchlauf;
    
       printf("Bitte einen Wert eingeben: ");
       fgets(s1,MAX,stdin);
       printf("Bitte noch einen Wert eingeben: ");
       fgets(s2,MAX,stdin);
    
       suchlauf=str_compare(s1, s2);
       printf("%d",suchlauf);
    }
    */
    
    int str_compare( char *s1, char *s2)
    {
       int laenge_s2=0, laenge_s1=0;
       int i=0, j=0;
       int index;
    
       while (s1[laenge_s1] != '\0')
       {
          laenge_s1++;
       }
    
       while (s2[laenge_s2] != '\0')
       {
          laenge_s2++;
       }
    
       for (i=0; i < laenge_s2||i<laenge_s1; i++)
       {
    printf("i=%d   s1+i=%c   s2+i=%c\n", i, *(s1+i) ,*(s2+i));
          if (*(s1+i) != *(s2+i))
          { 
             return (*(s1+i)-*(s2+i));
          }
       }
    
       return (*(s1+i)-*(s2+i));
    }
    

    (main methode wurde auskommentiert, da ich das in einer header datei speichern soll.. die datei, die eingelesen werden soll ist 1000 Zeilen lang und handelt von Gott.

    Danke schonmal..

    Liebe Grüße
    Nicole


  • Mod

    Schaaf schrieb:

    Danke schonmal..

    Gern geschehen, aber wofür?

    Ich weiß nicht so recht, was überhaupt deine Frage ist.



  • Vielleicht will er, dass wir seine Aufgabe lösen...



  • Die Aufgabenstellung ist Schwachfug hoch 3.
    strdup ist KEINE Standardfunktion, weder C89 noch C99.
    Kein Wunder, wenn die Schüler hier dauernd mit so einem Schrottwissen ankommen, da sie diesen Schrott offensichtlich nicht nur von diversen Buchautoren sondern auch von ihren Lehrern vermittelt bekommen.
    Bestelle deinem Lehrer mal einen schönen Gruß mit dem Hinweis, er soll selbst mal gründlich lernen bevor er lehrt.



  • Hast du die Funktion <str_compare> selbst geschrieben?
    Hast du vielleicht vergessen zu erwähnen, dass für Stringfunktionalitäten keine str-Funktionen verwendet werden dürfen (ja, solche Aufgabenstellungen soll es geben), ansonsten scheint mir diese haarsträubende Implementierung wenig sinnvoll, d.h. schau dir mal die Standard-str-Funktionen aus <string.h> an, dein Code wird kürzer, lesbarer, robuster ...


  • Mod

    Ach, sehen wir strdup mal als gegeben an. Meine Kristallkugel sagt mir, dass der Fragesteller keine Ahnung hat wie man etwas sortieren kann und keine hat Initiative dies selbst herauszufinden.

    Ratschlag: Bei solchen Problemen helfen immer ein paar Spielkarten, mit denen man das Problem am Schreibtisch anschaulich machen kann. Gehen wir mal davon aus, dass hier keine anspruchsvolle, hocheffiziente Sortierfunktion gesucht ist, sondern etwas einfaches. Dann könnte man so vorgehen (zur Vereinfachung mal nur Buchstaben A-E, aber vom Prinzip her gehts genau gleich):

    Unsortiert:
    DEACB
    Arraylänge: Fünf

    Erster Schritt:
    Suche kleinsten Wert im Array ab dem ersten Feld: A
    Tausche A mit erstem Wert: AEDCB

    Zweiter Schritt:
    Suche kleinsten Wert im Array ab dem zweiten Feld: B
    Tausche B mit zweitem Wert: ABDCE

    Dritter Schritt:
    Suche kleinsten Wert im Array ab dem dritten Feld: C
    Tausche C mit drittem Wert: ABCDE

    Vierter Schritt:
    Suche kleinsten Wert im Array ab dem vierten Feld: D
    Tausche D mit viertem Wert: ABCDE

    Nach vier Sortierschritten ist ein fünfelementiges Array auf jeden Fall sortiert.

    Dies ist zwar nicht sonderlich effizient, aber sehr einfach zu verstehen und zu programmieren.



  • Wir sollten die string_compare funktion selber schreiben, um sie zu verstehen.. klar könnten man die aus der string.h datei entnehmen, aber das durften wir nicht..

    ich versteh die ganze aufgabenstellung nicht.. wenn ich das so mache, wie ich den code hier geschrieben habe, folgen laufend fehler.. ist das richtig mit den zeilenweise einlesen? oder geht das anders, wenn man das in einem String schreiben muss.. ich weiß einfach nicht, wie ich da anfangen muss..


  • Mod

    Schaaf schrieb:

    Wir sollten die string_compare funktion selber schreiben, um sie zu verstehen.. klar könnten man die aus der string.h datei entnehmen, aber das durften wir nicht..

    ich versteh die ganze aufgabenstellung nicht.. wenn ich das so mache, wie ich den code hier geschrieben habe, folgen laufend fehler.. ist das richtig mit den zeilenweise einlesen? oder geht das anders, wenn man das in einem String schreiben muss.. ich weiß einfach nicht, wie ich da anfangen muss..

    Ja, das Einlesen ist ziemlich falsch. Arrays haben keine Kopiersemantik, daher kannst du so etwas wie s[i]=line; nicht machen (bzw. du kannst es machen, aber es macht nicht das was du denkst). Eben dafür wäre zum Beispiel die strdup geeignet, oder besser noch du liest gleich in s[i] ein.

    Sollte dies alles nicht in deinem Kurs drangekommen sein? Wie wutz erläutert hat, ist dein Kurs nicht besonders gut, aber trotzdem sollten zumindest ein paar Grundlagen gemacht worden sein.



  • Mach dich doch mal über die Funktion char *strdup(char *s) schlau.

    Wenn du weißt was die macht hilft das bei der Lösung.

    Nebenbei brauchst du die Funktion nicht schreiben, nur benutzen.



  • Ich hab jetzt nochmal n bissl rumgetüftelt und gefragt und hab mitlerweile das sortieren hinbekommen.. nur mit den einlesen will einfach nicht in meinen kopf rein -.-

    Also diese funktion string_compare war teil der 1. aufgabe. in frt 2. aufgabe dürfen wir wieder andere funktionen nutzen, müssen diese jedoch wieder einbinden..

    fragwürdig sind für mich die funktion readNumberFile(char*filename) und die Zeile 5 (..strdup..) muss ich die da oben hinschreiben!?

    (sorry, aber ich bin n bissl verwirrt wegen den ganzen kram..)

    #include <stdio.h>
    #include <string.h>
    #include "str_compare.h"
    void swap(char **a, char **b)
    char *strdup(char *s)
    
    int readNumberFile(char*filename)
    {
       int i=0;
       char line[300];
    
       FILE* open = fopen(filename,"r");
    
       while (!feof(open) && (i<1000))
       {  
          fscanf(open,"%s",line);
          s[i];
          i++
       }
       fclose(open);
       return i;
    }
    void str_sort(char *l[], int n)
    {
    
    	int i,j;
    
    	/* Daten sortieren */
    	for( i=0; i<(n-1); i++ )
    	{
        	for( j=i+1; j<n; j++ )
        	{
    
            	if( str_compare(l[i],l[j]) > 0 )
                	swap( &l[i], &l[j] );
    
        	}
    	}
    	return;
    }
    
    void swap(char **a, char **b)
    {
    
    	char *t;
     	t = *a;
    	*a = *b;
    	*b =  t;
    	return;
    
    }
    

    als Fehlermeldung kommt das raus:

    2.c: In function swap': 2.c:8: error: syntax error before "int" 2.c:13: error: parameteropen' is initialized
    2.c:13: error: `filename' undeclared (first use in this function)
    2.c:13: error: (Each undeclared identifier is reported only once
    2.c:13: error: for each function it appears in.)
    2.c:13: confused by earlier errors, bailing out

    str *dup dupliziert doch den string von s, oder? Warum muss man denn in diesen fall was dupliezieren.. ich soll doch zeilenweise einlesen, da reicht es doch, wenn ich ein String habe..


  • Mod

    Sei mal etwas freigiebiger mit den Semikolons, dies ist nicht PASCAL.



  • Erstmal gehören in Zeile 4 und 5 Semikolons ans Ende.
    Bzw. Zeile 5 brauchst du nicht da das auch in <string.h> steht.

    str *dup dupliziert doch den string von s, oder? Warum muss man denn in diesen fall was dupliezieren.. ich soll doch zeilenweise einlesen, da reicht es doch, wenn ich ein String habe..

    Du liest in deiner Schleife die Datei zeilenweise ein.
    Jedes mal in das selbe Array.
    Frage: Welche Zeile steht am Ende der Schleife im Array?

    2.c:8: error: syntax error before "int"

    ist schon mal ein Folgefehler aus Zeile 4
    Den erst beheben, dann verschwinden auch ein paar andere Fehler. (Dafür werden dann neue gefunden 😞 )


Anmelden zum Antworten