the_clapper
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
Hallo,
ich benötige ein Programm, welches aus einer Datei mit festem Format Zahlen einliest. Habe google bemüht und danke fscanf ist die Funktion, die ich brauche. Da ich c-Neuling bin habe ich es mit einem einfachen Testprogramm probieren wollen, aber bisher habe ich folgendes Problem. Das Programm:
#include <stdio.h>
int main(void)
{
int x;
FILE *datei;
datei = fopen("100.txt", "r");
if(NULL == datei)
{
printf("Fehler beim Öffnen");
}
fscanf(datei, "%d", x);
printf("x = %d \n", x);
fclose(datei);
return 0;
} liefert beim kompilieren mit gcc folgende Warnung:
a.c: In Funktion »main«:
a.c:15: Warnung: format »%d« erwartet Typ »int *«, aber Argument 3 hat Typ »int« Und das Programm liefert, wenn ich es ausführe folgenden Fehler:
Segmentation fault Ich denke, wenn ich die Fehlermeldung verstünde, wäre mir schon geholfen. Kann mir jemand erklären, wovor gewarnt wird? In der Datei 100.txt steht in der ersten Zeile ohne Leerzeichen davor "100" (ohne die Anführungszeichen.
|
Sid_Burn
Anmeldungsdatum: 23. Oktober 2004
Beiträge: 2159
|
the clapper schrieb: a.c: In Funktion »main«:
a.c:15: Warnung: format »%d« erwartet Typ »int *«, aber Argument 3 hat Typ »int«
Ich denke, wenn ich die Fehlermeldung verstünde, wäre mir schon geholfen. Kann mir jemand erklären, wovor gewarnt wird?
C erwartet einen Zeiger(Pointer) auf einen int. Das sagt der Stern aus, der steht für Zeiger. Du hast aber direkt ein int übergeben. Mit einem & vor einer Variable bekommt man die Adresse einer Variablen. Daher musst du wohl eher soetwas schreiben. fscanf(datei, "%d", &x);
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Zudem läuft Dein Programm nach einem möglichen Fehler einfach weiter, ich würde das Aaslesen daher in einen else-Zweig packen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #include <stdio.h>
int main(void)
{
int x;
FILE *datei;
datei = fopen("100.txt", "r");
if(NULL == datei) {
printf("Fehler beim Öffnen");
} else {
fscanf(datei, "%d", &x);
printf("x = %d \n", x);
fclose(datei);
}
return 0;
}
|
Dann noch zwei Fragen:
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
erstmal vielen Dank. Jetzt funktioniert mein Beispiel und ich denke ich habe auch in etwa verstanden, was der Fehler war. Also der Kontext ist folgender: Ich habe Dateien in der Form:
Ganzzahl Ganzzahl Fließkommazahl Es sind Punkte, die in eine PostGreSQL Datenbank gespeichert werden sollen. Im ersten Schritt wollte ich mir einer Eingabe-Datei für psql schreiben, die ich dann per psql -d "dbname" -f "input-file" einlade. Habe das per Hand getestet, dafür aber jetzt das C-Programm. Im zweiten Schritt würde ich gerne die Eingabe-Datei umgehen und direkt in die Datenbank speichern. Da alleine die reinen Punkte-Dateien mehrere hundert MB groß sind dürften die Eingabe-Dateien für psql noch viel größer werden und somit unhandlich. Ich habe allerdings noch keine Ahnung, ob es möglich ist direkt aus einem kleinen Programm in die Datenbank zu schreiben. Die Programmiersprache ist egal, solange unter Ubuntu/Debian einfach zu "erreichen". C, C++ oder Fortran wären ideal. Perl oder Java weniger, aber zur Not ginge das auch. Ich freue mich über jede Anregung.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Also da würde ich mal dieses Python Script vorschlagen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
import postgresql
import sys
def get_values(filename):
"""
Generator function which parses a file with the given filename and yields
data values for each line.
"""
funcs = [int, int, float]
with open(filename, "r") as infile:
for line in infile:
tokens = line.strip().split()
yield [func(value) for func, value in zip(funcs, tokens)]
def main():
db = postgresql.open("pq://username:password@localhost/postgres")
store_values = db.prepare("INSERT INTO whatever VALUES ($1, $2, $3)")
with db.xact():
store_values.load_rows(get_values(sys.argv[1]))
if __name__ == "__main__":
main()
|
Neben der Standard Lib wird nur noch dieser PostgreSQL-Connector benötigt. Da ich keine Postgres-DB hier hatte, konnte ich den DB-Teil nicht testen. Laut Doku sollte das aber so funktionieren. Du musst halt in Zeile 21 die Verbindungsdaten anapssen und in Zeile 22 den Tabellennamen.
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
Vielen Dank. Ich werde das gleich heute Abend noch testen. Wo hast Du das her? Oder hast Du es etwa gerade selbst geschrieben?
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
the clapper schrieb: Vielen Dank. Ich werde das gleich heute Abend noch testen. Wo hast Du das her? Oder hast Du es etwa gerade selbst geschrieben?
Natürlich letzteres 😉 Als kleine Fingerübung quasi ☺
Wenn Du es relativ schnell testest, bin ich noch online falls etwas mit der DB nicht funzt. Den Teil konnte ich ja leider nicht testen. Ach ja, die Daten-Datei musst Du als Parameter beim Aufruf übergeben. Hatte ich nicht dazugeschrieben ☺
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
Ich stehe etwas auf dem Schlauch, wäre sehr nett, wenn Du mir noch weiter helfen könntest. Folgendes habe ich gemacht. 1) Python 3.1 installiert
2) Den von Dir empfohlenen "Konnektor" py-postgresql-1.0.1 installiert über sudo python3.1 ./setup.py install Jetzt Dein Script abspeichern, aber als was? Als .py Datei? Und dann den Aufruf wie? ./script.py -dateiname ? Habe bisher noch nichts mit Python zu tun gehabt.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Also ich hab es mit Python 2.6.5 entwickelt! K.A. ob es auch mit Python 3.x läuft. Der Aufruf muss ohne das "-" erfolgen - ist ja keine Option.
Du musst es natürlich auch noch mit chmod ausführbar machen, oder das ganze mit python aufurfen:
| python script.py datei_name
|
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
Der Konnektor hat bei der Installation gemeckert und nach 3.1 oder höher verlangt. Ich erhalte folgenden Fehler
Traceback (most recent call last):
File "./script.py", line 4, in <module>
import postgresql
ImportError: No module named postgresql
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
the clapper schrieb: Der Konnektor hat bei der Installation gemeckert und nach 3.1 oder höher verlangt.
Ah... ok
Ich erhalte folgenden Fehler
Traceback (most recent call last):
File "./script.py", line 4, in <module>
import postgresql
ImportError: No module named postgresql
Das bedeutet, dass Python das Modul nicht finden kann. Ich habe folgende Vermutung: Wenn Du unter ubuntu arbeitest, dann hast Du ja nebenher noch python 2.6 installiert. /usr/bin/env wird auf dieses verweisen, welches logischerweise das Modul nicht kennt. (Module liegen bei Python immer in einem Verzeichnis namens site-packages, welches sich direkt auf eine Interpreter-Version bezieht) Hier steht dazu was:
http://wiki.ubuntuusers.de/Python#Python-3 Also ändere den She-bang oben eben um:
| #!/usr/bin/python3
# oder evtl auch so
#!/usr/bin/env python3
|
Musst Du mal probieren ☺
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
mit #!/usr/bin/python3.1 läuft es es. Sehr gut, danke schön. Allerdings habe ich beim INSERT INTO irgendwo einen Syntax-Fehler. Den werde ich wohl so schnell nicht beheben können, da ich meine Aufzeichnungen, in denen der richtige Befehl steht, leider nicht hier habe. Werde es morgen früh probieren und Dir dann Rückmeldung geben. Vielen Danke nochmal. edit: nachdem ich den Datenbank-Namen angepasst habe arbeitet er jetzt. Ist leider ein sehr langsamer Test-Server. Schätze mal das wird noch einige Minuten dauern...
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
the clapper schrieb: edit: habe den Befehl noch im Kopf gehabt:
INSERT INTO punkte (spalte) VALUES (ST_makePoint(5.5,5.5,5.5)); funktioniert leider nicht. ST_makePoint kommt aus postGis, einer Erwieterung für PostrgreSQL.
Tja... was heißt denn "funktioniert" nicht? Wie äußert sich das?
|
the_clapper
(Themenstarter)
Anmeldungsdatum: 3. Juli 2009
Beiträge: 134
|
Danke. Alles bestens! Da war ich mit post&edit etwas voreilig. Nochmals vielen, vielen Dank. Du hast mir wirklich einiges an Recherche gespart.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
the clapper schrieb: Danke. Alles bestens! Da war ich mit post&edit etwas voreilig. Nochmals vielen, vielen Dank. Du hast mir wirklich einiges an Recherche gespart.
Also funzt es? ☺
|