Csv Datei in C einlesen, strtok



  • @hustbaer
    das macht mein o.g. Code so; sscanf ist unerlässlich für komfortable Fehlerchecks innerhalb der Zeile.
    Und dem Code ist es auch egal, ob es 12 GB oder 12 TB Daten sind.



  • Ich muss nochmals etwas fragen. Ich verwende den Code von Wutz, funktioniert auch prima. Nur möchte ich nun die while Schleife abbrechen sobald eine bestimmte Taste gedrückt wird. Dies möchte ich aus verschiedenen Gründen so machen. Ich frage die Tastatureingabe mit kbhit() ab, das funktioniert auch. Nur wenn ich das so aktuell mache dauert das ewig lange (12TB Datei). Habe dazu im Programm die Zeit gemessen. Zum Vergleich ohne die Abfrage mit kbhit() läuft das Programm ca. 200 Sekunden. Mit der Tastaturabfrage läuft das Programm sehr lange. Ich habe da nach 2000 Sekunden abgebrochen.

    Meine Frage: Kennt Ihr eine andere Möglichkeit wie ich die while Schleife verlassen kann, mit einemTastendruck ohne kbhit()? Habe dazu nix nennenswertes gefunden. So wie ich es sehe braucht diese Tastaturabfrage sehr lange.

    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <conio.h>
    
    char *strrev(char *str)
    {
          char *p1, *p2;
    
          if (! str || ! *str)
                return str;
          for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
          {
                *p1 ^= *p2;
                *p2 ^= *p1;
                *p1 ^= *p2;
          }
          return str;
    }
    
    
    
    int main()
    {
        clock_t time_start = clock();
        FILE *x=fopen("daily.txt", "r");
    
    
        char s[1000],a[1000],b[1000],c[1000],d[1000],e[1000],f[1000],g[1000];
        while( fgets(s,1000,x) )
        {
             if(kbhit())
                {
                int key = getch();
                if(key == 'y')
                    {
                        break;
                    }
                }
    
    
            int n1,n2;
            char t[1000];
            if( 2==sscanf(s,"%s%s%n",a,b,&n1) )
            if( 4==sscanf(strrev(strcpy(t,s)),"%s%s%s%s%n",g,f,e,d,&n2) )
            if( 1==sscanf(s+n1+1,"%[^\n]",c) )
            c[strlen(c)-n2]=0;printf("%s%s%s%s%s%s%s\n",a,b,c,strrev(d),strrev(e),strrev(f),strrev(g));
        }
    
        fclose(x);
    
        clock_t time_end = clock();
    
        clock_t duration = time_end - time_start;
    
        double zeit = (double)duration / CLOCKS_PER_SEC;
    
        printf("zeit: %lf\n", zeit);
    
        getch();
    
        return 0;
    }
    
    


  • @jasmin89
    kbhit&Co sind selbst die Ursache für die Verlangsamung und außerdem auch nicht standardkonform.
    Was willst du denn mit deinem Abbruch erreichen?
    Dass du kaputte Daten hast und nochmal neu starten musst?!
    Du kannst die Schleifendurchläufe zählen und zB nur bei jedem 100. die Tastatur abfragen, vielleicht hilft das.



  • @Wutz Hallo, danke für den Tipp. Ich werde es versuchen. Ich möchte, während die Datei eingelesen wird nach einem bestimmten Wort suchen und diese Zeile printen. Sobald die Zeile gefunden wurde will ich das mit einer Taste abbrechen. Das Problem ist dass mehrere Zeilen das Wort beinhalten und nur ich selbst als „Mensch“ kann beurteilen ob die richtige Zeile gefunden wurde. Damit wird halt nicht die ganze Datei dursucht sondern nur so weit wie nötig

    Nur aus interesse: Verwendet die Windows Suche eigentlich auch die Funktion khbit()? Denn da kann ich ja auch mit Esc abbrechen. Oder ist die Windows Suche „intelligenter“ aufgebaut? Die Windows Suche müsste ja in C/C++ programmiert sein.



  • @jasmin89 sagte in Csv Datei in C einlesen, strtok:

    Oder ist die Windows Suche „intelligenter“ aufgebaut?

    Ja.
    Die verwendet die Windows-API und da laufen Dinge parallel.

    Die Windows Suche müsste ja in C/C++ programmiert sein.

    Kann auch C# sein, oder ...



  • @jasmin89 sagte in Csv Datei in C einlesen, strtok:

    @Wutz Hallo, danke für den Tipp. Ich werde es versuchen. Ich möchte, während die Datei eingelesen wird nach einem bestimmten Wort suchen und diese Zeile printen. Sobald die Zeile gefunden wurde will ich das mit einer Taste abbrechen. Das Problem ist dass mehrere Zeilen das Wort beinhalten und nur ich selbst als „Mensch“ kann beurteilen ob die richtige Zeile gefunden wurde. Damit wird halt nicht die ganze Datei dursucht sondern nur so weit wie nötig

    Wenn du das Programm komplett abbrechen willst, dann kannst du auch einfach Ctrl+C drücken. Das sollte funktionieren ohne dass du extra dafür etwas programmierst.

    Nur aus interesse: Verwendet die Windows Suche eigentlich auch die Funktion khbit()? Denn da kann ich ja auch mit Esc abbrechen. Oder ist die Windows Suche „intelligenter“ aufgebaut? Die Windows Suche müsste ja in C/C++ programmiert sein.

    Die Suche im Windows Explorer verwendet sicher nicht khbit(), da Explorer kein Konsolenprogramm ist. Den Tastatur-Input bekommt Explorer vermutlich wie die meisten anderen Windows-Anwendungen über Window-Messages.



  • Danke für die Hilfe, hier wird weitergeholfen. Ich rufe nun nur alle 1000 Iterationen mal khbit() auf und das funktioniert prima. Hier noch mein Codeschnipsel als Lösung.

    int count = 0;
    
    while( fgets(s,1000,x) )
        {
                        if(count>1000)
                        {
                             if(kbhit())
                            {
                            int key = getch();
                            if(key == 'y')
                                {
                                    break;
                                }
                            }
                            count=0;
                        }
                
                        count++;
    .
    .
    .
    .
    
           }
    


  • @jasmin89 Kreative Einrückungen.

    for (int count = 0; fgets(buffer, 1000, input_file); ++count) {
        if (count > 1000 && kbhit()) {
            int key = getch();
            if (key == 'y')
                break;
            count = 0;
        }
        // do something with buffer
    }
    


  • @Swordfish sagte in Csv Datei in C einlesen, strtok:

       if (count > 1000 && kbhit()) {
    

    Da wird aber ab 1000 immer das langsame kbhit() aufgerufen, wenn keine Taste gedrückt wurde.

    if (count > 1000 && !((count = 0)) && kbhit()) {
    // ja, count wird auf 0 gesetzt. Doppelklammern, damit der Compiler keine Warnung gibt.
    

    PS: Das funktioniert wegen der https://de.wikipedia.org/wiki/Kurzschlussauswertung



  • Achje, ne, dann lieber das 2. if lassen.

    Oder, wenn's denn wirklich unbedingt super-kompakt sein muss:

            if (!(count & 0x3FFu) && kbhit() && getch() == 'y')
                break;
    

    Mit unsigned count, weil sonst UB bei Überlauf.


Anmelden zum Antworten