frank(SMSii) schrieb:> while(dateiZeiger){> fscanf(dateiZeiger, "%d %d %d", &hunderter &zehner &einer);> summe=hunderter*100+zehner*10+einer;
Das würde dir bei dieser Datei
221 253 028 060 092 123 155 186 218 249 025 056 088 119 151 182 214 246
die 221 nach hunderter, die 253 nach zehner und die 28 nach einer
einlesen. Bist du sicher das du das willst? Deine Variablennamen deuten
eigentlich auf etwas ganz anderes hin.
> Dann versteh ich nicht ganz wie die fscanf(); Funktion funktioniert,> bzw. wird der Zeiger(dateiZeiger) automatisch erhöht?
Ja.
> Gibt es einen> Fehler wenn die lücke zwischen den Zahlen erreicht ist?
das regelt alles der Formatstring
Vielleicht wäre ein Blick in ein Grundlagenbuch wirklich nicht soooo
verkehrt.
Deine while Schleife rundeherum ist auch verkehrt.
Nein, ein Blick in ein Grundlagenbuch wäre wirklich nicht verkehrt.
Dein Formatstring ("%d %d %d") passt nicht auf das Eingabeformat. Bei
dem ersten Aufruf von fscanf() werden bereits 221 253 028 eingelesen.
Und wie folgt zugewiesen
hunderter = 221
zehner = 253
einer = 28
Du könntest eine dreistellige Zahl nach der anderen lesen und die
Variablen dann per Programm füllen.
while(dateiZeiger){
fscanf(dateiZeiger, "%d", &summe);
hunderter = summe / 100;
zehner = (summe / 10) % 10;
einer = summe % 10;
summe = hunderter*100 + zehner*10 + einer;
cout << summe << endl;
}
Mit einem "%d" als Formatstring liest die fprintf-Funktion eine
komplette Dezimalzahl aus der Datei bis zum nächsten Trennzeichen
(Leerzeichen oder NewLine), ob die einstellig, wie bei dir dreistellig,
oder neunstellig ist, was Du da drumrumgebaut hast, mit der Addition der
Dezimalstellen ist nämlich schon drin.
mfG ingo
Hallo Karl,
> Vielleicht wäre ein Blick in ein Grundlagenbuch wirklich nicht soooo> verkehrt.
mein Problem ist, ich habe hier ein Grundlagenbuch vom RRZN(Regionales
Rechenzentrum Niedersachsen). Da steht aber nur wenig drüber drin,
deshalb frage ich.
>> Deine while Schleife rundeherum ist auch verkehrt.> Nein, ein Blick in ein Grundlagenbuch wäre wirklich nicht verkehrt.>
Danke für die Info, dann weiß ich bescheid.
Tschö
Okay,
nochmal eine Frage.
Was mache ich, wenn ich nicht weiß wieviele Zahlen ich in der Datei
habe?
Wäre es möglich Dateien die gerade beschrieben werden, auch gleich
wieder auszulesen (echtzeit?) ?
Beste Grüße
frank(SMSii) schrieb:> Hallo Karl,>>> Vielleicht wäre ein Blick in ein Grundlagenbuch wirklich nicht soooo>> verkehrt.>> mein Problem ist, ich habe hier ein Grundlagenbuch vom RRZN(Regionales> Rechenzentrum Niedersachsen). Da steht aber nur wenig drüber drin,> deshalb frage ich.
fscanf funktioniert genau gleich wie scanf.
Nur dass es von einer Datei liest und nicht von der Eingabekonsole.
Aber die Bedeutung der Zeichen im Formatstring ist völlig identisch zum
scanf Fall. Wer mit scanf umgehen kann, kann auch mit fscanf (und
sscanf) umgehen.
Aber abgesehen davon.
Da du ja die C++ Konsolne Stream Ausgabe über cout benutzt und
wahrscheinlich auch die Stream-Eingabe über cin: Warum benutzt du dann
nicht die C++ Streams?
Auch hier wieder: Innerhalb dieser Familie an Funktionalitäten ist alles
identisch, lediglich das Stream Objekt ist ein anderes. In dem einen
Fall ist es ein (bereits vorhandenes) Objekt cin, im anderen Fall muss
man sich ein ein File Stream Objekt selber erzeugen. Das ist aber keine
Hexerei.
Und ehrlich: Wenn dein Skript da nicht näher darauf eingeht, dann wirf
es weg. File Handling ist ein wichtiges Thema und jedes C oder C++ Buch
hat ein umfangreiches Kapitel darüber. Greif im Bücherregal zu den
Klassikern und nicht zu irgendwelchen esoterischen Machwerken, bei denen
der Autor in vielen Fällen selbst nicht wusste, worüber er da eigentlich
schreibt.
frank(SMSii) schrieb:> Was mache ich, wenn ich nicht weiß wieviele Zahlen ich in der Datei> habe?
'Was mache ich'
in welcher Hinsicht?
Musst du die Zahlen irgendwo speichern? Oder was ist dein Problem.
Zum Thema: woher weiß ich, das die Datei zu Ende ist:
Jede Einlesefunktion hat einen Returnwert, der unmittelbar darüber
Auskunft gibt, ob das Einlesen geklappt hat oder nicht. Wenn da ein
Fehler auftritt UND danach eine Abfrage des EOF Status der Datei ein eof
(End of File) ergibt, dann wurde die Datei vollständig gelesen.
> Wäre es möglich Dateien die gerade beschrieben werden, auch gleich> wieder auszulesen (echtzeit?) ?
Wozu?
Du weißt ja was du geschrieben hast.
Aber um die Frage zu beantworten: Ja, das ist möglich. Man muss die
Datei read/write eröffnen und dann mittels (f)tell() und (f)seek()
ständig hin und her 'springen'.
Karl heinz Buchegger schrieb:> Greif im Bücherregal zu den> Klassikern und nicht zu irgendwelchen esoterischen Machwerken, bei denen> der Autor in vielen Fällen selbst nicht wusste, worüber er da eigentlich> schreibt.
Irgendwelche Empfehlungen?
frank(SMSii) schrieb:> Karl heinz Buchegger schrieb:>> Greif im Bücherregal zu den>> Klassikern und nicht zu irgendwelchen esoterischen Machwerken, bei denen>> der Autor in vielen Fällen selbst nicht wusste, worüber er da eigentlich>> schreibt.>> Irgendwelche Empfehlungen?
C: Kernighan & Ritchie 'Programmieren in C'
C++: Stroustroup 'The C++ Programming Language' (gibts
wahrscheinlich auch auf Deutsch
Wenn dann schon ein kleiner Grundstock an C++ Praxis vorhanden ist:
Scott Meyers "Effective C++"
Scott Meyers "More Effective C++"
Meyers hängt aber davon ab, dass du den Stroustroup schon durch hast.
Ohne das Grundlagenwissen aus dem Stroustroup ist der Meyers sinnlos,
weil du nicht verstehst, wovon er da eigentlich spricht und warum die
'Problemkreise' die Meyers anspricht, überhaupt Probleme sind, die
gelöst werden müssen.
Vlad Tepesch schrieb:> frank(SMSii) schrieb:>> Ich habe eine Datei, mit folgendem Inhalt:>>>> 221 253 028 060 092 123 155 186 218 249 025 056 088 119 151 182 214 246>> 021 053 084 116 147 179 210 242 017 049 081 112 144 175 207 238 014 045>> 077 108 140 171 203 235 010 042 073 105 136 168 199 231 006 038 069 101>> 133 164 196 227 003 034 066 097 129 160 192 223 255 031 062 094 125 157>> 188 220 251 027 058 090 121 153 185 216 248 023 055 086 118 149 181 212>> 244 019 051 083 114 146 17>> Ich vermute mal du, must hier auch aufpassen, dass die Parser die Zahlen> mit einer 0 am Anfang nicht als Oktalzahl interpretieren.
Nope:
Die Regel, dass eine Zahl mit einer führenden 0 eine Oktalzahl ist, gilt
nur innerhalb des C Source Codes.
Stream lesen ist davon nicht betroffen.
Karl heinz Buchegger schrieb:> Nope:> Die Regel, dass eine Zahl mit einer führenden 0 eine Oktalzahl ist, gilt> nur innerhalb des C Source Codes.> Stream lesen ist davon nicht betroffen.
Ok, da war ich mir nicht sicher.
Vlad Tepesch schrieb:> Karl heinz Buchegger schrieb:>> Nope:>> Die Regel, dass eine Zahl mit einer führenden 0 eine Oktalzahl ist, gilt>> nur innerhalb des C Source Codes.>> Stream lesen ist davon nicht betroffen.>> Ok, da war ich mir nicht sicher.
Hatte früher auch so meine Probleme damit :-)
Aber wenn man einmal darüber nachdenkt, ist auch klar, dass man das auf
keinen Fall machen darf. Dein Benutzer hätte seine liebe Not damit, wenn
er bei einer Zahleneingabe führende 0-en eingibt. Das dann eigenmächtig
als Oktalzahl zu interpretieren, wäre höchst kontraproduktiv von den
Einlesefunktionen.
Hallo nochmal,
das mit dem Datei einlesen funktioniert jetzt. Dafür möchte ich ein
ähnliches Problem angehen.
Dazu verwende ich eine µC der Daten an die Serielle Schnittstelle
sendet, dabei handelt es sich immer noch um das schon oben beschriebene
Zahlenformat(hterm):
221 253 028 060 092 123 155 186 218 249 025 056 088 119 151 182 214 246
021 053 084 116 147 179 210 242 017 049 081 112 144 175 207 238 014 045
Nun möchte ich die Zahlen aber nicht erst umständlich in eine Datei
Speichern, sondern gleich im Programm verwerten.
Zum öffnen des COM1-Ports und einlesen der Werte benutze ich folgenden
Quelltext (ziemlich lang):
1
#include<stdio.h>
2
#include<windows.h>
3
#include<conio.h>
4
#include<stdlib.h>
5
6
#ifndef com_h_INCLUDED
7
#define com_h_INCLUDED
8
9
10
DWORDdwWritten;
11
12
DCBdcb;
13
COMMTIMEOUTScommtimeouts;
14
15
DWORDcommerr;
16
COMSTATcomstat;
17
DWORDbytes_read;
18
19
// Definition der seriellen Schnittstelle
20
// mehr Informationen siehe:: http://msdn.microsoft.com/de-de/library/aa363858(v=VS.85).aspx
21
22
#define lpFileName "Com1"
23
// Namen der zu öffnenden Schnittstelle angeben
24
#define dwDesiredAccess GENERIC_READ
25
// was soll am COMx-Port ausgeführt werden? _WRITE _READ (ODER-Verknüpft)
26
#define dwShareMode 0
27
// schließt den COMx-PORT für andere Programme!!
28
#define lpSecurityAttributes NULL
29
// Standard Sicherheits Beschreibung (NULL = Standard)
30
#define dwCreationDisposition OPEN_EXISTING
31
// Gerät muss angeschlossen sein --> sonst Fehleraufruf: ERROR_FILE_NOT_FOUND
Das nun auftretende Problem ist das Zahlenformat, welches ich erhalte
und das sieht folgendermaßen aus:
4199534 4199469 4199527 4199502 4199543 4199535 4199543 4199535 4199527
4199502 4199543 4199535 4199541 4199535 4199463 4199534 4199543 4199503
4199527 4199531 4199541 4199502 4199461 4199502 4199506 4199426 4199463
4199503 4199426 4199506 4199490 4199504 4199541 4199498 4199490 4199501
4199527 4199534 4199543 4199531 4199527 4199498 4199477 4199499 4199461
4199530 4199525 4199498 4199442 4199525 4199502 4199525 4199498 4199442
Die Kennzahlen für die Übertragung lauten:
BAUD: 115200
Bitanzahl: 8
Parity: None
Stopbits: 1
also 8N1.
Kann mir jemand sagen ob er/sie das Problem sieht?
Beste Grüße
Frank
frank(SMSii) schrieb:> Quelltext (ziemlich lang):
Wichtige Regeln - erst lesen, dann posten!
•Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
> Kann mir jemand sagen ob er/sie das Problem sieht?
Deine Daten vom uC sind vermutlich garnicht als ASCII codiert wie du es
ursprünglich behauptet hast...
Läubi .. schrieb:>> Kann mir jemand sagen ob er/sie das Problem sieht?> Deine Daten vom uC sind vermutlich garnicht als ASCII codiert wie du es> ursprünglich behauptet hast...
Könnte aber doch sein.
Das Problem könnte sein, dass er hier
1
if(com_geti(&com_inputi,hComm)==TRUE){//Serielle Schnittstelle nach neuen Zeichen abfragen
2
printf("%d \n",com_inputi);//das Empfangene Zeichen in der Konsole ausgeben
3
fprintf(fdatei,"%d ",com_inputi);//das Empfangene Zeichen in die Datei schreiben
4
}
nicht das Zeichen, sondern den ASCII Code des Zeichens ausgibt.
Mir scheint, dem TO ist noch gar nicht klar, dass das hier
"089"
erst mal nur ein String, bestehend aus Zeichen ist und keine Zahl. Eine
Sequenz von Zeichen wird aber nicht magisch zu einer Zahl, sondern man
muss etwas dafür tun.
Ändere erst mal so um
1
if(com_geti(&com_inputi,hComm)==TRUE){//Serielle Schnittstelle nach neuen Zeichen abfragen
2
printf("%c \n",com_inputi);//das Empfangene Zeichen in der Konsole ausgeben
3
fprintf(fdatei,"%c ",com_inputi);//das Empfangene Zeichen in die Datei schreiben
4
}
und sieh nach, ob in der Datei dann das steht was du erwartest.
Alternativ, und das wäre auf lange Sicht die bessere Lösung, sollte die
Funktion
1
intcom_geti(int*com_inputi,HANDLEhComm){
das tun, was ihr Funktionsname verspricht: Einen Integer empfangen.
Genau das tut sie zur Zeit nicht. Sie empfängt ein Zeichen. Ein Zeichen
ist aber kein Integer. Um da einen Integer zu empfangen musst du solange
Zeichen sammeln, bis eines daher kommt, welches sicher nicht mehr zur
Zahl gehören kann. Und erst diese Sequenz von Zeichen kann in einen
Integer umgewandelt werden.
ziemlicher Schwachsinn.
Du liest genau 1 Byte ein und legst das in einem int ab. Ein int hat
aber mehr als 1 Byte und wenn man einmal nachverfolgt, wo dieser int
herkommt, dann haben wir wieder mal: eine uninitialisierte Variable.
1
intcom_inputi;
2
while(1){
3
4
if(com_geti(&com_inputi,hComm)==TRUE){//Serielle Schnittstelle nach neuen Zeichen abfragen
5
printf("%d \n",com_inputi);//das Empfangene Zeichen in der Konsole ausgeben
6
fprintf(fdatei,"%d ",com_inputi);//das Empfangene Zeichen in die Datei schreiben
7
}
8
}
Da du von den Bytes, die einen int ausmachen, nur 1 Byte gezielt auf
einen Wert setzt, ist es nicht weiter verwunderlich, dass du da auf der
Ausgabe wilde Zahlen erhältst.
Das mindeste wäre
1
intcom_inputi=0;
Aber wie bereits gesagt: Die ganze Funktion com_geti ist falsch. Sie
macht nicht das, was sie tun sollte. Nämlich mehrere
hintereinanderfolgende Zeichen zu empfangen und daraus eine Zahl zu
generieren, die den empfangenen Zeichen entspricht.