Frage zu Sequentiellen Dateien



  • Hallo, bin neu hier,
    hab im moment das problem das ich seit 2 jahren kein C mehr gesehen hab, daher ist mein wissen ein wenig beschränkt, habe mich aber seit her mit anderen Programmiersprachen auseinandergesetzt, wissen ist also da, nur nich bei C 🙂

    nun habe ich das problem das ich gerne aus einer text datei folgendes auslesen möchte

    servername\benutzername
    servername\benutzername2
    servername\benutzername3
    servername\benutzername4
    

    so sähe die Text datei aus...
    das problem is das die benutzernamen jeweils verschiedene Längen haben.
    wie bekomm ich die jetzt eingelesen und das servername\ vorne rausgeschnitten?

    habe mir dazu schon zig beispiel programme reinzogen aber nix davon konnt ich auf meine bedürfnisse abändern, soll auch nur ne vorab lösung sein.

    ich müsste die benutzernamen in nem array o.ä haben da diese später wieder zurück in die datei geschrieben werden müssten...

    Die Text datei soll praktisch umformatiert werden,
    nu is die frage wie mach ich das jetzt?!
    bitte helft mir!



  • 😃 Auf die Gefahr hin, das ich aus allen Foren verbannt werde. 😃
    Nimm zum lösen das Programm awk, das ist auf solche Sachen spezialsiert

    Im anderen Fall hier eine C-Lösung exemplarisch, sie funktioniert kann aber mit viel Liebe noch ausgebaut werden.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char* argv[])
    {
    char buffer[256+1]; // das +1 ist eine Marotte 
                        // von mir um den üblichen Fehler zu vermeiden das für
                        // die schließende Null kein Platz mehr da ist.
    char *buffer2;
    unsigned int i;
    while (!feof(stdin))
     {
      buffer[0]=0x00;
      if (NULL==fgets(buffer,256,stdin))
          break;
      for (i=0;i<strlen(buffer);i++)
        if ('\\'==buffer[i])
           {
              buffer2=&(buffer[i+1]);
              printf(buffer2);
           }
      }
    return 0;
    }
    

    Viel Spaß



  • PAD schrieb:

    😃 Auf die Gefahr hin, das ich aus allen Foren verbannt werde. 😃
    Nimm zum lösen das Programm awk, das ist auf solche Sachen spezialsiert

    Brain Kernighan hat awk miterfunden, es ist also fast on topic :).

    while (!feof(stdin))
    

    feof ist eine sehr gewöhnungsbedürftige Funktion, die man im für solche Fälle getrost ignorieren kann.

    if (NULL==fgets(buffer,256,stdin))
    

    Du darfst da ruhig die 256 durch 257 austauschen. fgets terminiert selbstständig. Aber was man nicht alles tut um Buffer Overruns zu vermeiden ... man lässt sogar bewusst Felder frei.

    for (i=0;i<strlen(buffer);i++)
    

    Ungünstig. Erst mal rattert strlen durch den gesamten String (im Zweifelsfall bei jedem Durchlauf) und dann humpelst Du gleich nochmal drüber. Wenn man unbedingt mit Indices arbeiten will, dann ist 'for (i = 0; buffer[i]; ++i)' das Mittel der Wahl.

    printf(buffer2);
    

    Gedankenspielerei: buffer2 ist '%d', dann würde printf ein Argument erwarten. Besser 'printf("%s", buffer2)' oder (am besten) 'fputs(buffer2, stdout)'.



  • ich glaube ich wurde leicht missverstanden,

    hab mich jetzt soweit durchgeackert das ich dies hier zum laufen gebracht hab

    #include "stdio.h"
    #include "string.h"
    
    	char  Data[80];
    	char pToken;
    	FILE *file;
    
    void main()
    {		
      file = fopen("test.txt", "r");
    
    	while (!feof(file))
    	{	
    	fgets(Data, 80, file);
    	printf("%s\n",Data);
    	}
    	fclose(file);
    }
    

    So hier mal die TExtfile de nun geändert werden muss

    NT AUTHORITY\INTERACTIVE
    NT AUTHORITY\Authenticated Users
    NT2S-CIM7\ipmonitor
    NT2S-CIM7\monitor
    NT2S-CIM7\kroeber1
    NT2S-CIM7\Hotline
    NT2S-CIM7\nms
    NT2S-CIM7\Aydin
    NT2S-CIM7\Backup
    NT2S-CIM7\csieora
    NT2S-CIM7\csiespass
    NT2S-CIM7\Durham
    NT2S-CIM7\CIM7
    NT2S-CIM7\Shannon
    
    

    ich brauch aba in nem array in etwa diese form
    array[1] = ipmonitor
    array[2] = monitor
    array[3] = hotline

    der rest muss RAUS, wie mach ich das nu? strtok hab ich schon probiert aber da gibts nur fehler beim compilen...



  • @Daniel E.
    Jetzt gehts an die Verteidigung:

    Punkt 1 ok, aber alte Gewohnheiten legt man schwer ab, speziell dann wenn man so wias in 2-5 Minuten runterschreibt, while (1) oder for ( ; ; )
    täten es genauso.
    ➡ (An alle) Bitte keine Philospiediskussion was von den beiden das bessere wäre. Ich nutz die beiden nach Lust und Laune, trotz oder wegen der letzten Diskussion.

    Punkt 2 Da hab ich eine andere Auffassung. ich allokiere prinzipell bei strings mit argument + 1 um den Platz für das trailing Zero
    zu markieren und benutze immer die davor definierte Stringlänge. Deswegen steht ja auch das mit der Marotte da
    Das fgets an dieser Stelle sicher ist ist schön und gut. An anderen Stellen sind andere Funktioen, eigene Konstrukte, Konstrukte aus libraries, arbeiten von Kollegen die sind es nicht immer.

    Punkt 3 ok, gute Idee da definitiv schneller(bißchen kryptisch aber wofür hat man schließlich eine schließende 0)

    Punkt 4 ok, hast eine orginelle Fehlermöglichkeit aufgezeigt. das "%s" ist die sinnvolle Verbesserung da sie zu stabilerem Code führt, kann glücklicher weise allerdings nach Spezifikation hier nicht auftreten

    Ich freue mich das

    sie funktioniert kann aber mit viel Liebe noch ausgebaut werden.

    so sportlich angenommen hast.

    eine neugierige Frage wie lange hat die Korrektur gedauert?

    @Wommi
    Deine Lösung ist ein vernünftiger Ansatz

    -leg dir deine 3 Felder mit den strings in passender Größe an

    Erhöhe in der Leseschleife für jeden Durchlauf einen Counter der ist der Zeiger in deine Arrays und beginnt mit 0
    zerleg Data in die 3 teil in dem du die bis zum jeweiligen Delimiter in das entsprechende Array kopierts
    vergiss nicht an jeden Teil die abschließende 0 anzufügen
    und schon hast du es
    Schau die in dem Zusammenhang die Funktion strcopy an.

    Lies mein Besipiel und die Kommentare von Daniel E un es müßte funktionieren

    Mißverstanden wurdest du nicht, deine Speuzifikation war zwar nicht vollständig aber die neue ist auch nicht wesentlich anders



  • Hi,

    ich hab mich mal dran versucht. Würde mich freuen, wenn sich das mal wer anguckt und mir sagt, was man noch besser machen könnte bzw. was fehlerhaft ist. Oder beides 😃

    #include <stdio.h>
    #include <string.h>
    #define MAX 80
    
    int  main()
    {
            char Data[MAX];
            char *pToken[MAX];
            char *merken;
            char trennzeichen='\\';
            int i=0;
    
            FILE *file;
            file = fopen("test.txt", "r");
    
            while (!feof(file))
            {
                    fgets(Data, MAX, file);
                    merken = strchr(Data, trennzeichen);
    
                    merken++;
    
                    pToken[i]=(char*)malloc(MAX);
    
                    strcpy(pToken[i], merken);
                    i++;
            }
    
            printf("%s", pToken[4]);
            fclose(file);
            return 0;
    }
    

    Oder mit Strtok:

    #include <stdio.h>
    #include <string.h>
    #define MAX 80
    
    int main()
    {
            char Data[MAX];
            char *pToken[MAX];
            int i=0;
            FILE *file;
    
            file = fopen("test.txt", "r");
    
            while (!feof(file))
            {
                    fgets(Data, MAX, file);
                    strtok(Data, "\\");
                    (char*)pToken[i] = strtok(NULL, "");
    
                    printf("%s", pToken[i]);
                    i++;
            }
            fclose(file);
    }
    


  • PAD: Zu Punkt 1, der feof-Problematik: Das Problem dieser Funktion ist, dass sie erst dann 'wahr' liefert, wenn der Stream das Ende schon erreicht hat (also 'überlesen' wurde). Dann sind für fgets keine Zeichen mehr da, es gibt 0 zurück und im Puffer bleibt der alte Inhalt stehen. Hättest Du nicht noch die zusätzliche Bedingung in deinen Code geschrieben wäre er falsch gewesen. Das alles wäre nicht notwendig gewesen, wenn man einfach 'while (fgets(...))' hätte anfangen lassen.

    Eine Anwendungsmöglichkeit für feof ist, dass plötzlich nach einem fgetc oder ähnlichem ein EOF auftritt. Um jetzt zu diagnostizieren, ob es sich um einen Fehler (ferror) oder das ganz normale Ende gehandelt hat, benötigt man feof.



  • Probier ich aus



  • @Daniel E. Hab´s probiert sieht gut aus.

    @Wommi Probiers mal damit

    #define NUMBERofENTRIES 100  // Damit kann ich maximal 100 Einträge speichern
    int main(int argc, char* argv[])
    {
      // Nutzdaten
      char feld[NUMBERofENTRIES][256+1]; // Feld zum Speichern der Ergebnisse
      int err=0; // Fehlercode  
      // Hilfsvariablen
      char buffer[256+1]; // Arbeitsbuffer zum lesen der Daten
      int k=0;   // Entry in Array
      int i;     // Hilfsindex
      int j;     // Hilfsindex
      int flag;  // Delimiter gefunden
      while (fgets(buffer,256,stdin))
      {
        j=0;
        flag=false;
        for (i=0;i<buffer[i];i++)
        {
          if ('\\'==buffer[i])
          {
            flag=true;
            i++;
          }
          if (true==flag)
            feld[k][j++]=buffer[i];
        }
        feld[k++][j]=0x00;
        if (k>=NUMBERofENTRIES)
        {
          printf("\nERR >!!! Fehler zu viele Einträge !!!\n");
          err=1;
          break;
        }
      }
      //in k ist jetzt die Anzahl der Einträge
      for(i=0;i<k;i++)
        printf("%s\n",feld[i]);
      return err;
    }
    

    Nachdem compilieren aufrufen mit progname <inputfile >outputfile



  • letzteres ergibt bei mir nur compiler fehler 😞

    #include "stdio.h"
    #include "string.h"
    
    	char Data[20]; 
            char *pToken[20];
    	FILE *file;
    	int i=0; 
    
    void main()
    {	
    
    	file = fopen("test.txt", "r");
    
    	// Hier werden die ersten 2 Zeilen vernichtet... die müssen auch raus
    	fgets(Data, 80, file); 
    	fgets(Data, 80, file); 
    
    	while (!feof(file))
    	{
             	fgets(Data, 80, file); 
                    strtok(Data, "\\"); 
                    (char*)pToken[i] = strtok(NULL, ""); 
    
    		printf("%s", pToken[i]); 
    
                    i++;
    
    	}	 
    	fclose(file);
    }
    

    danke an carstenJ mittlerweile läufts "fast" so wie es soll.. 🙂

    http://www.etechnik-schiller.de/ausgabe.jpg
    aber wat is das nu?
    das sonderzeichen vor dem "monitor" ? wo kommt das her
    und warum hab ich da unten jetzt (null) stehen?



  • Die (null) ist eindeutig

    da du nachdem fgetrs fehlgeschlagen ist noch einmal ein printf machst.

    Hier nochmal die Bitte, schau dir den gelieferten Sourcecode und die Kommentare dazu an, damit du solche Fehler vermeidest.

    Nicht umsonst hat Daniel E. auf die Probleme der feof Lösung hingewiesen.
    Nicht unmsonst habe icn in meiner lösung das fgets in einem if

    Trotzdem Viel Spaß


Anmelden zum Antworten