(In C) Zeilen werden beim Einlesen verschluckt

Buba235

Erfahrenes Mitglied
Hallo Leute!


Ich hab mich ja in letzter Zeit schon öfter Mal bei euch hier im Forum gemeldet und ich hab auch immer super gute Hilfe bekommen. Nur jetzt hab ich ein Problem, das ich nicht lösen kann, weil es keine Fehler gibt. Mein Programm kopiert eine txt Datei in mein Verzeichnis (das ist nur so weil ich die Originaldatei nicht beschädigen o.ä. will). Die Kopie läuft einwandfrei. Alles soweit korrekt! Nachdem das geschehen ist, werden einzelne Strings aus jeder Zeile ausgelesen und in eine neue Datei geschrieben (das hat nur den Sinn zu überwachen, ob alle Zeilen gelesen wurden). Hier ist jetzt das Problem: Es werden immer die letzten Zeilen verschluckt und nicht mit eingelesen. Die Anzahl der verschluckten Zeilen ist von Datei zu Datei verschieden, aber immer die gleiche Anzahl bei der gleichen Datei. Ich geb euch mal den Code hier an, vielleicht findet ihr ja nen Fehler!

Code:
/*Includes*/
#include <stdio.h>
#include <mysql.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


/*Defines*/
#define LINE_SIZE 1024


/*Prototypen*/
int connect_DB();
char* mystrtok(char*, char);
void close_conect(MYSQL*);
void read_file();
void filecopy(FILE*, FILE*);
void strings_ausgeben(FILE*);
void erease_file();
void writeInDatabase(MYSQL*);


/*globale Variablen*/
extern int errno;


/*----------------------------------------------------------------------------*/
/*Hauptfunktion main startet das Programm*/
int main(int argc, char *argv[]) {

        /*Funktion aufrufen und Programm starten*/
        read_file();
        connect_DB();

        return 0;
}/*Ende der Funktion main*/

/*----------------------------------------------------------------------------*/
/*Diese Funktion stellt eine Verbindung zur Datenbank (Alarmmanager) her*/
int connect_DB() {

        /*Variablen*/
        MYSQL *conn;        /*Fuer Verbindung benoetigt*/

        /*Verbindungsaufbau zum MySQL-Server mit Fehlerabfrage*/
        conn = mysql_init(NULL);
        if (mysql_real_connect( conn,
                                "2.9.153.47",
                                "root",
                                "root",
                                "alarmmanager",
                                3306,
                                NULL,
                                0) == NULL) {
                fprintf(stderr, "Fehler mysql_real_connect(): "
                        "%u (%s)\n", mysql_errno(conn), mysql_error(conn));
                exit(EXIT_FAILURE);
        }

        /*Funktionsaufrufe*/
        writeInDatabase(conn);
        close_conect(conn);     /*DB-Verbindung schliessen*/

        return 0;
}/*Ende der Funktion connect_DB*/


/*----------------------------------------------------------------------------*/
/*Mit Hilfe dieser Funktion wird die Verbindung zur Datenbank wieder
  geschlossen und der belegte Speicher wird frei gegeben*/
void close_conect(MYSQL *mysql) {

        mysql_close(mysql);
}/*Ende der Funktion close_conect*/


/*----------------------------------------------------------------------------*/
/*In dieser Funktion wird das Textfile ausgelesen und der Inhalt an die
  Funktion filecopy uebergeben*/
void read_file() {

        /*Variablen*/
        FILE *datei_org;
        const char *path = "/home/tracer/trace_history/060521/filter/2006_05_21_06_WLAN_DB.txt";

        /*Datei zum Lesen oeffnen*/
        datei_org = fopen(path, "rt");
        if (datei_org == NULL) {
                perror("Fehler beim Oeffnen der Datei(Funktion read_file) ");
                exit(EXIT_FAILURE);
        }

        /*Aufruf der Funktion*/
        filecopy(datei_org, stdout);    /*Quelldatei kopieren*/


        /*Datei schliessen*/
        fclose(datei_org);
}/*Ende der Funktion read_file*/


/*----------------------------------------------------------------------------*/
/*Diese Funktion kopiert den Inhalt einer Quell-Datei in eine Ziel-Datei*/
void filecopy(FILE *org, FILE *datei_ziel) {

       /*Variablen*/
        int c;
        const char *path = "/home/tracer/wlan_DB/alert_files/2006_05_21_06_WLAN_DB.txt";

        /*Datei zu Schreiben oeffnen*/
        datei_ziel = fopen(path, "wt");
        if (datei_ziel == NULL) {
                perror("Fehler beim Oeffnen der Datei(Funktion filecopy) ");
                exit(EXIT_FAILURE);
        }

        /*Einlesen des Inhalts in die Ziel-Datei*/
        while((c = getc(org)) != EOF) {
                putc(c, datei_ziel);
        }

        /*Funktionsaufruf*/
        strings_ausgeben(datei_ziel);   /*Zeichenkette ermitteln*/

        /*Datei schliessen*/
        fclose(datei_ziel);

        /*Datei loeschen um Speicherplatz zu sparen*/
        erease_file();
}/*Ende der Funktion filecopy*/


/*----------------------------------------------------------------------------*/
/*Hier wird die Zeichenkette ermittelt, die spaeter auch in die Datenbank
  eingetragen werden soll (Zeile fuer Zeile)*/
void strings_ausgeben(FILE *datei) {

        /*Variablen*/
        int i;
        FILE *super;
        char *word = NULL;
        char gelesene_Kommas = ',';
        char buffer[LINE_SIZE];
        const char *path = "/home/tracer/wlan_DB/alert_files/2006_05_21_06_WLAN_DB.txt";
        const char *pfadzuSuper = "/home/tracer/wlan_DB/alert_files/super.txt";

        /*Datei anlegen*/
        super = fopen(pfadzuSuper, "wt");
        if (super == NULL) {
                perror("Fehler beim Oeffnen der Datei(Funktion strings_ausgeben) ");
                exit(EXIT_FAILURE);
        }

        /*Datei zum Lesen oeffnen*/
        datei = fopen(path, "rt");
        if (datei == NULL) {
                perror("Fehler beim Oeffnen der Datei zum Auslesen(Funktion strings_ausgeben) ");
                exit(EXIT_FAILURE);
        }

        /*Jede Zeile durchgehen und immer den String einlesen*/
        while(fgets(buffer, LINE_SIZE, datei) != NULL) {
                word = mystrtok(buffer, gelesene_Kommas);
                for(i = 0; word != NULL; i++) {
                        if (i == 12) {
                                /*Das Eingelesene wird in die Datei
                                  super.txt geschrieben*/
                                fprintf(super, "%s\n", word);
                                break;
                        }
                        word = mystrtok(NULL, gelesene_Kommas);
                }
        }

        /*Datei schliessen*/
        fclose(datei);
        fclose(super);
}/*Ende der Funktion datei_ausgeben*/


/*----------------------------------------------------------------------------*/
/*Diese Funktion uebernimmt die Aufgabe der C-eigenen Funktion strtok()
  Mit der C-eigenen Funktion wurden leere Teile zwischen den Kommas
  ueberlesen und der naechste Wert wurde ausgegeben. Diese Funktion
  arbeitet sauberer*/
char* mystrtok(char *s, char delim) {

        /*Variablen*/
        char *curr = NULL;
        char *ret = NULL;
        static char *buffer = NULL;

        if (s) {
                buffer = s;
        }

        curr = buffer;

        if (curr) {
                while(*curr != delim && (*(curr++)) != '\0');

                if (*curr == '\0') {
                        return NULL;
                }

                *curr = '\0';
                ret = buffer;
                buffer = curr + 1;
        }

        return ret;
}/*Ende der Funktion mystrtok*/


/*----------------------------------------------------------------------------*/
/*Bei dieser Funktion wird die zu Anfangs kopierte Datei wieder geloescht*/
void erease_file() {

        /*Pfadangabe*/
        const char *path = "/home/tracer/wlan_DB/alert_files/2006_05_21_06_WLAN_DB.txt";

        /*Hier wird die zu Anfangs kopierte Datei geloescht, 
          um Speicher zu sparen*/
        if ((remove(path)) < 0) {
                perror("Fehler beim Loeschen(Funktion erease_file) ");
                exit(EXIT_FAILURE);
        }
}/*Ende der Funktion erease_file*/


/*----------------------------------------------------------------------------*/
/*Diese Funktion schreibt den Inhalt der Datei in die Datenbank*/
void writeInDatabase(MYSQL *conn) {

        /*Variablen*/
        const char *sql;

        /*SQL-Befehl*/
        sql = "LOAD DATA LOCAL INFILE \
        '/home/tracer/wlan_DB/alert_files/super.txt' \
                        INTO TABLE tblamwlan \
                        LINES TERMINATED BY '\n' \
                        (AlarmText)";

        /*Daten des Files in die Tabelle schreiben*/
        mysql_query(conn, sql);

        /*Fehlerabfrage*/
        if (sql != 0) {
                fprintf(stderr, "%s\n", mysql_error(conn));
                fprintf(stderr, "%s\n", sql);
                exit(EXIT_FAILURE);
        }
}/*Ende der Funktion writeInDatabase*/

Das ist jetzt mein komplettes Programm! Testen kann man es ja nur wenn man bestimmte Teil weg lässt, aber das ganz Programm funktioniert so, wie es eben soll. Mit Ausnahme der verschluckten Zeilen. Ich habe mich jetzt damit einige Tage abgemüht, aber finde den Fehler nicht.
 
Hi.

In der mystrtok Funktion ist noch ein Fehler drin. Änder das mal so
C:
while (*curr != delim && *curr != '\0') curr++;
Evtl. sind deine Zeilen ja auch länger als 1024 Zeichen?

Gruß
 
Hallo!


Also ich hab die Funktion jetzt mal angepasst. Leider hat es nur einen geringen Erfolg erzielt. Ich hab eine Zeile mehr rausholen können. Das mit den 1024 Zeichen hab ich auch schon auf alllen möglichen Werten probiert. Der letzte Wert war 1,000,000! Ich weiß einfach nicht mehr weiter! Hat sonst jemand eine Idee?
 
Wie sehen denn die verschluckten Zeilen aus? Wieviel Kommas sind da drin? Endet eine Zeile immer mit einem Komma?

Gruß
 
Hallo!

Einige der letzten Zeilen enden mit einem Komma, weil dahinter wieder einiges Strings leer sind, aber andere enden ganz normal mit einem \n. Wie ich auch schon sagte, verschluckt er mir von Datei zu Datei unterschiedliche Anzahlen von Zeilen. Durch die Änderung in der Funktion mystrtok() bekomm ich jetzt eine Zeile mehr ausgegeben!
 
Hier mal die Datei (zumindest eine der Dateien). Es ist die kürzeste, die ich gefunden habe! Sie ist im Anhang.

Das sind jetzt 371 Zeilen und er gibt mir 366 Zeilen aus! Jetzt kannst du das ja mal testen. Du musst ja nichts in eine Datenvbank eintragen. Aber mit der Datei und dem Code muss es ja gehen!
 

Anhänge

  • 24566attachment.txt
    56,9 KB · Aufrufe: 56
Also ich hab es jetzt ausprobiert und bei mir werden keine Zeilen verschluckt.

Die Datei hat bei mir 228 Zeilen und es wurden sogar 229 Zeilen ausgegeben weil die LINE_SIZE zu klein war. Als ich die LINE_SIZE entsprechend vergrößert hatte wurden alle 228 Zeilen ausgegeben.

Evtl. stimmt da etwas mit deiner Kopiererei nicht.

Gruß
 
Hallo!


Hast recht. Es funktioniert wenn ich direkt auf die Datei zugreife, ohne sie vorher zu kopieren. Ich weiß nicht was genau falsch läuft beim kopieren (oder vielleicht wird sie ja sogar gelöscht bevor er mit Auslesen fertig ist), aber jetzt hab ich zumindest den Ansatz!

Danke für deine Hilfe!
 
Hallo deepthroat hat schon recht...

Erhoehe doch mal die LINE_SIZE. Deine Zeilen in der Datei sind zu lang...

Code:
#define LINE_SIZE 4096
sollte erstmal genuegen...

Gruß

RedWing
 
Zurück