Forum: PC-Programmierung Problem mit fopen_s in C


von Robert B. (rsb89)


Lesenswert?

Guten Morgen,

ich möchte gern eine .txt-Datei in meinem C-Programm öffnen und den 
Inhalt in einen String einlesen. Ich Programmiere in Visual-Studio! Der 
Compiler "mag" die Funktion fopen nicht, daher nehme ich fopen_s zum 
öffnen der Datei. Die Funktion gibt 0 zurück, was. soweit ich weiß, 
"kein Fehler" bedeutet. Im übergebenen File-Pointer steht bei "_ptr" 
aber NULL. Ich habe schon eine weile gesucht, finde aber nirgends einen 
Hinweis auf meinen Fehler.
1
#include <stdio.h>
2
#include <string.h>
3
4
#define INPUTFILE "input.txt"
5
6
int main(int argc, char *argv[])
7
{
8
  FILE *input;
9
10
  if((fopen_s(&input, INPUTFILE, "r+")) != 0)
11
        ...
12
}

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Moin,

eine der besten kostenfreien Onlinequellen:
http://openbook.galileocomputing.de/c_von_a_bis_z/016_c_ein_ausgabe_funktionen_026.htm

Die Beispiele funktionieren und die Beschreibung ist gut.

Grüße aus Berlin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Robert B. schrieb:
> Der Compiler "mag" die Funktion fopen nicht

Das ist nur eine Warnung. Die kann man abschalten:

#pragma warning(disable:4996)

von Robert B. (rsb89)


Lesenswert?

Danke, mit fopen klappt es besser!

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Hallo,

du könntest ja jetzt sagen was du anders gemacht hast. Das würde auch 
anderen helfen die nächste Woche über das gleiche Problem stolpern und 
die Suchfunktion im Forum benutzten.

Das machen zwar nicht viele, aber vielleicht hilft es ja :-)

von cybmorg (Gast)


Lesenswert?

Hat er doch: Er benutzt jetzt fopen und schaltet die Warnung ab.

von Robert B. (rsb89)


Lesenswert?

Ich habe Rufus' Tip umgesetzt (#pragma warning(disable:4996)) und 
arbeite jetzt mit fopen(). ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Microsoft hat sich zwar was dabei gedacht, als sie die Warnung 4996 
eingeführt haben, aber sie haben nicht weit genug oder zu weit gedacht.

Es gibt diverse Funktionen in der C-Laufzeitumgebung, die historisch 
gewachsen sind und die Einfalltore für Sicherheitslücken, Speicherlecks 
o.ä. sind. Den Programmierer dazu zu bewegen, diese Funktionen nicht 
mehr zu nutzen, sondern auf sicherere Varianten umzusteigen, ist keine 
schlechte Idee.

So ist beispielsweise strcpy ein Problem, weil es nicht die Länge des 
Zielpuffers überprüfen kann.

Microsoft schlägt hier eine nur auf MS-Compilern verfügbare Funktion 
strcpy_s vor, die sich nur durch die Reihenfolge der Argumente von 
strncpy unterscheidet.

Der Hintergedanke ist wohl, daß immer Pointer und Mengenangabe direkt 
aufeinanderfolgen sollen.

Derartige Problemzonen gibt es viele, und an vielen dieser Problemzonen 
ist das auch sehr sinnvoll.

Allerdings treibt Microsoft es zu weit, indem sie auch eher 
unproblematische Funktionen wie fopen und tatsächlich auch strncpy 
benörgelt.

Und da wird die gut gemeinte Absicht zu Schwachsinn.

Ergo: Abschalten. Und "von Hand" darauf achten, kein strcpy o.ä. zu 
verwenden.

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Danke an Rufus!
Das ist doch mal eine echte Erklärung.

von Mark B. (markbrandis)


Lesenswert?

Wenn man in C programmieren will, dann kann man freilich auch gleich 
einen Compiler verwenden, der den Standard C99 unterstützt.

Damit ist MS leider raus. Hach wie schade ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Damit ist MS leider raus. Hach wie schade ;)

Kann man machen. Damit verzichtet man aber auch auf so ziemlich den 
besten verfügbaren Debugger.

Ich habe bislang kein überzeugendes Argument gehört, das dafür spricht, 
zwingend C99 verwenden zu müssen.

(Wobei die "Argumentation" von MS, warum sie keinen C99-konformen 
C-Compiler herausbringen wollen, auch an Peinlichkeit nur schwer zu 
überbieten ist: Das "Argument" lautet: "Wer C99 braucht, soll doch 
einfach C++ verwenden ...")

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Allerdings treibt Microsoft es zu weit, indem sie auch eher
> unproblematische Funktionen wie fopen und tatsächlich auch strncpy
> benörgelt.

Der Unterschied zwischen den an sich schon sicheren C-Funktionen wie
fopen und strncpy und ihren MS-Äquivalenten liegt wohl neben dem
geänderten Aufruf ausschließlich darin, dass in den MS-Funktionen die
Pointer-Argumente auf ungleich NULL überprüft werden. Zusätzliche
Sicherheit wird dadurch aber nicht gewonnen, da die Dereferenzierung
eines Null-Pointers sowieso einen Segfault auslöst.

Mark Brandis schrieb:
> Wenn man in C programmieren will, dann kann man freilich auch gleich
> einen Compiler verwenden, der den Standard C99 unterstützt.

Hat sich in C99 gegenüber C90 irgendetwas geändert, was die Lösung des
hiewr diskutierten Problems erleichtern würde?

Rufus Τ. Firefly schrieb:
> Ich habe bislang kein überzeugendes Argument gehört, das dafür spricht,
> zwingend C99 verwenden zu müssen.

Es gibt auch keins, denn statt zu C99 kann man auch gleich zu C11
übergehen ;-)

Damit fällt MS natürlich noch etwas weiter hinter die aktuelle
Entwicklung zurück, und das Argument, stattdessen C++ zu verwenden,
greift noch weniger. Aber sei's drum: Neue Windows-Applikationen werden
sowieso nicht mehr in C programmiert, und bestehende C-Applikationen
müssen brauchen nicht den neuesten C-Standard. Somit gibt es kaum Gründe
für MS, C weiter zu unterstützen.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Microsoft schlägt hier eine nur auf MS-Compilern verfügbare Funktion
> strcpy_s vor, die sich nur durch die Reihenfolge der Argumente von
> strncpy unterscheidet.

Open Watcom kennt die auch ...
1
errno_t strcpy_s( char * restrict s1,
2
                  rsize_t s1max,
3
                  const char * restrict s2 );

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Hallo Rufus,

Rufus Τ. Firefly schrieb:
> Microsoft hat sich zwar was dabei gedacht, als sie die Warnung 4996
> eingeführt haben, aber sie haben nicht weit genug oder zu weit gedacht.
>
> Es gibt diverse Funktionen in der C-Laufzeitumgebung, die historisch
> gewachsen sind und die Einfalltore für Sicherheitslücken, Speicherlecks
> o.ä. sind. Den Programmierer dazu zu bewegen, diese Funktionen nicht
> mehr zu nutzen, sondern auf sicherere Varianten umzusteigen, ist keine
> schlechte Idee.
>
> [...]
>
> Allerdings treibt Microsoft es zu weit, indem sie auch eher
> unproblematische Funktionen wie fopen und tatsächlich auch /strncpy/
> benörgelt.
>
> Und da wird die gut gemeinte Absicht zu Schwachsinn.

Wenn Entwickler mit der Warnung dazu gebracht werden, die 
Ersatzfunktionen anstatt der standardisierten Originale zu benutzen, ist 
der Quellcode nicht mehr portabel und die Wettbewerber ausgesperrt... 
Wenn man sich dann einmal anschaut, wie Microsoft sich seines 
Wettbewerbers DR-DOS entledigt hat 
(http://en.wikipedia.org/wiki/AARD_code) werden unschöne Erinnerungen an 
diese und andere FUD-Strategien wach, etwa bei Java.

Liebe Grüße,
Karl

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Da gab es auch mal ähnliche Probleme mit NetWare ...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Käfer schrieb:
> Wenn Entwickler mit der Warnung dazu gebracht werden, die
> Ersatzfunktionen anstatt der standardisierten Originale zu benutzen ...

Eben. Es hätte völlig gereicht, bei strcpy, gets und der ganzen 
lausigen scanf -Familie eine Warnung auszugeben und in der 
Dokumentation auf die Varianten mit Mengenangabe zu verweisen, statt 
redundante Funktionen mit anderen Namen und inkompatiblem Aufruf zu 
erfinden.

Naja, mit dem o.g. Pragma oder der korrespondierenden 
Compilereinstellung ist das Thema ja aus der Welt zu schaffen.

von Dirk B. (dirkb2)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Microsoft schlägt hier eine nur auf MS-Compilern verfügbare Funktion
> strcpy_s vor, die sich nur durch die Reihenfolge der Argumente von
> strncpy unterscheidet.

strcpy_s hängt auf alle Fälle eine '\0' ans Ende
strncopy macht dies nicht, wenn der Quellstring >= der angegebenen 
Anzahl ist.

Auch strncat und strcat_s verhalten sich unterschiedlich.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Dirk B. schrieb:
> Auch strncat und strcat_s verhalten sich unterschiedlich.

was mich nicht wundert ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was spricht dagegen, das Verhalten von strncpy und strncat zu 
ändern?

In den mittlerweile 25 Jahren, die ich mein Geld mit C verdiene, habe 
ich dieses spezifische "Feature" nie benötigt, noch ist mir ein Fall 
untergekommen, wo es hätte sinnvoll sein können.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Joachim Drechsel schrieb:
>> strncat und strcat_s

Es sind nun wirklich unterchiedliche Funktionen.

von Rolf Magnus (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Microsoft schlägt hier eine nur auf MS-Compilern verfügbare Funktion
> strcpy_s vor, die sich nur durch die Reihenfolge der Argumente von
> strncpy unterscheidet.
>
> Der Hintergedanke ist wohl, daß immer Pointer und Mengenangabe direkt
> aufeinanderfolgen sollen.

Bei solchen Aktionen habe ich immer eher den Eindruck, daß der 
Hintergedanke ist, dem Programmierer die Benutzung einer Funktion 
aufzuschwatzen, die zum Rest der Welt inkompatibel ist.

Rufus Τ. Firefly schrieb:
> Ich habe bislang kein überzeugendes Argument gehört, das dafür spricht,
> zwingend C99 verwenden zu müssen.

Zwingend verwenden muß man es nicht. Man muß ja auch nicht zwingend C89 
verwenden. Es gibt ja auch noch K&R C. Es stellt sich nicht die Frage, 
ob zwingend nötig, sondern ob es nützlich und praktisch wäre, es nutzen 
zu können.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Es gibt ja auch noch K&R C. Es stellt sich nicht die Frage,
> ob zwingend nötig, sondern ob es nützlich und praktisch wäre, es nutzen
> zu können.

Das ist hart am Trollbeitrag. Der Unterschied zwischen K&R-C und C89 ist 
ganz erheblich, wo aber ist C99 tatsächlich so nützlich und praktisch, 
wie Du zu suggerieren scheinst?

Welches C99-spezifische Sprachfeature vereinfacht beispielsweise Dir 
die Arbeit?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Welches C99-spezifische Sprachfeature vereinfacht beispielsweise Dir
> die Arbeit?

Du hast schon recht: Der Schritt von C90 nach C99 ist ein viel kleinerer
als der von K&R nach C90. Trotzdem setzt C99 es ein paar wichtige Dinge
um, die vorher allenfalls als Spracherweierungen existierten. Die drei
wichtigsten sind aus meiner Sicht:

- Zeilenkommentare (//)

- Integer-Datentypen mit vorgegebener (Mindest-)Bitbreite

- Die neuen Funktionen snprintf und vsnprintf

Zudem erlaubt C99 endlich einen einheitlichen Umgang mit booleschen
Werten (der allerdings oft im Konflikt mit bestehendem C-Code steht).

Der eine oder andere Physiker oder Elektroingenieur mag sich sicher auch
am Datentyp complex erfreuen.

Auch die "Compound Literals" sind mitunter ganz praktisch.

: Bearbeitet durch Moderator
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Die drei wichtigsten sind aus meiner Sicht:
>
> - Zeilenkommentare (//)
>
> - Integer-Datentypen mit vorgegebener (Mindest-)Bitbreite
>
> - Die neuen Funktionen snprintf und vsnprintf

Nun, die drei Punkte erfüllt auch der nicht-C99-konforme 
Microsoft-C-Compiler der in VS2010 enthalten ist.

Wenn auch mit der kleinen Einschränkung, daß snprintf nur mit 
vorangestelltem Unterstrich verfügbar ist.

Bis auf stdint.h sind das Features, die ich schon zu Zeiten von VC 6 
genutzt habe ... und lange davor; der Zeilenkommentar wird wohl schon 
sehr lange toleriert.

Habe mal in alten Sourcen gegraben, und ein 20 jahre altes C-File 
gefunden, in dem ich auch schon Zeilenkommentare genutzt habe. Das war 
damals der mit dem Win32-SDK ausgelieferte Microsoft-C-Compiler, genaue 
Versionsnummer habe ich jetzt nicht parat. _snprintf gab es damals auch 
schon.

Seit wann Microsoft stdint.h (in ernstgemeint) kennt, muss ich zu meiner 
Schande gestehen, nicht zu wissen.

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Somit gibt es kaum Gründe für MS, C weiter zu unterstützen.

Siehe da, zumindest ein bisschen bewegen sie sich doch:

http://arstechnica.com/information-technology/2013/06/c99-acknowledged-at-last-as-microsoft-lays-out-its-path-to-c14/


Zitat:
"The final version of 2013 will also include a few C99 features. 
Microsoft has long avoided supporting C99, the major update to C++'s 
predecessor that was standardized last millennium, claiming that there 
was little demand for it among Visual Studio users. This was true, but 
only to a point; it's true that many Windows developers weren't 
especially interested in C99 because they had no good tooling to support 
it. Open source developers, however, embraced the update, as it makes C 
a lot less awkward to work with.

While full C99 support is still not in the cards, Sutter said that 
certain specific features were going to be added, including C99's 
compound literals and direct initializers. These additions will mean 
that many open source projects will become buildable in Visual Studio 
without demanding significant code changes. Sutter mentioned widely used 
video codec library ffmpeg as a specific example of a project that would 
work given these compiler improvements."

von Klaus W. (mfgkw)


Lesenswert?

2013-1999 = 14

Da soll noch einer sagen, die IT-Welt wäre kurzlebig.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Nun, die drei Punkte erfüllt auch der nicht-C99-konforme
> Microsoft-C-Compiler der in VS2010 enthalten ist.

Das ist ja super, dann liegt MS ja doch nicht so weit abseits, wie alle
immer denken :)

> Bis auf stdint.h sind das Features, die ich schon zu Zeiten von VC 6
> genutzt habe ... und lange davor; der Zeilenkommentar wird wohl schon
> sehr lange toleriert.

Klar, natürlich sind viele der C99-Features schon vor der offiziellen
Veröffentlichung des Standards implementiert worden, aber da waren es
eben noch Spracherweiterungen, die streng genommen nicht standardkonform
waren.

Auch die Funktionsprototypen – eines der zentralen Features des
ANSI-C-Standards von 1989 – gab es schon in der ersten GCC-Version
(0.9), die schon zwei Jahre früher erschien (natürlich wussten die
GCC-Entwickler aus Vorveröffentlichungen schon, wie der Standard in etwa
aussehen würde).

Mit der gleichen Begründung, mit der man C99 ablehnt, könnte man auch
ANSI-C bzw. C90 ablehnen, da man ja auch mit entsprechend erweiterten
K&R-Compilern (wie dem Ur-GCC) in den Genuss der wesentlichen
C90-Features kommt.

Generell nutze ich nicht standardisierte Spracherweiterungen, wenn
überhaupt, nur in privaten Hobbyprojekten..

Wenn aber ein Auftraggeber (Chef oder Kunde) von mir ANSI-C oder C90
verlangt, dann erfülle ich seinen Wunsch konsequent und verwende bspw.
keine Zeilenkommentare. Man geht damit von vorneherein potentiellen
Scherereien aus dem Weg. So hatte bei einem Kunden aus der Autobranche,
der auf ANSI-C bestand, der Code-Checker neben vielen anderen Dingen
richtigerweise auch Zeilenkommentare rigoros zurückgewiesen (die von der
Firma eingesetzten C-Compiler wären übrigens C99-konform gewesen).

Hat der Auftraggeber bezüglich des C-Standards hingegen keine Präferenz
und will einfach nur C, dann halte ich mich selbstverständlich an den
aktuellsten Standard (derzeit C11), da mit dem Erscheinen einer neuen
Ausgabe die bisherigen Ausgaben offiziell ungültig werden. Trotzdem
setze ich die neuen Features mit Bedacht ein, um ggf. eine Portierung
auf nicht ganz aktuelle Compiler nicht unnötig zu erschweren.

Nur auf den MS-C-Compiler, der mutwilligerweise auf den Stand vor einem
Vierteljahrhundert eingefroren worden ist, nehme ich keine Rücksicht :D
was ist bei Embedded-Projekten zum Glück auch nicht nötig ist. Aber da
nach dem von Mark verlinkten Artikel MS inzwischen gewillt zu sein
scheint, wenigstens ein paar der verschlafenen jahre wieder aufzuholen,
wird am Ende sowieso alles gut :)


Was ich in diesem Zusammenhang ganz witzig finde:

Das Kommentarsymbol // stammt ursprünglich gar nicht von C++, sondern
von BCPL aus dem Jahre 1966, einem Vorläufer von C. Die B- und
C-Entwickler entschieden sich aber für das mehrzeilige /* ... */ aus
PL/I. Erst nach einer viele Jahre dauernden Odysse über C++ und Java ist
das // schließlich auch offiziell in C angekommen :)

von Dirk B. (dirkb2)


Lesenswert?

Wenn man dmals die Zeilenkommentare in C-Programmen hatte, konnte man 
sagen, dass man C++ programmiert. :-D

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Wenn aber ein Auftraggeber (Chef oder Kunde) von mir ANSI-C oder C90
> verlangt, dann erfülle ich seinen Wunsch konsequent und verwende bspw.
> keine Zeilenkommentare. Man geht damit von vorneherein potentiellen
> Scherereien aus dem Weg. So hatte bei einem Kunden aus der Autobranche,
> der auf ANSI-C bestand, der Code-Checker neben vielen anderen Dingen
> richtigerweise auch Zeilenkommentare rigoros zurückgewiesen (die von der
> Firma eingesetzten C-Compiler wären übrigens C99-konform gewesen).

Versteh ich jetzt nicht. C99 ist doch auch ANSI-C. Oder?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Versteh ich jetzt nicht.

Stimmt.

von Mark B. (markbrandis)


Lesenswert?

Und wo ist das Problem? Wenn der Code-Checker nach C99 Standard prüft, 
sind // Kommentare selbstverständlich in Ordnung. Oder 
Variablendeklarationen, die nicht direkt am Anfang einer Funktion 
stehen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Oder Variablendeklarationen, die nicht direkt am Anfang
> einer Funktion stehen.

Präziser: Am Anfang eines Blockes.

Und da scheiden sich die Geister - das mag der C-Compiler von Microsoft 
(in VC2010 und älter) nicht.

Also:
1
int bla(int fusel)
2
{
3
  int x;
4
5
  x = machwas();
6
7
  int y;  // *1*
8
9
  for (int i = 0; i < 7; i++)
10
  {
11
    int z; // *2*
12
13
    //...
14
  }
15
}

Fall 1 wird von nicht-C99-konformen C-Compilern angekreidet, Fall 2 ist 
jedoch bereits mit C89 legal gewesen.


Nun gibt es verschiedene Ansichten darüber, ob diese Art der 
Variablendefinition wünschenswert ist.

Manche meinen, daß Variablen frühestens dort definiert werden sollen, wo 
sie das erste mal verwendet werden, eine andere Sichtweise ist es, alle 
Variablen innerhalb eines Blocks an dessen Anfang zu definieren, um 
einen Überblick darüber zu haben, welche denn überhaupt definiert 
werden.

Hängt man der einen Sichtweise an, stört einen das Fehlen dieses 
Features (der Variablendefinition nicht nur am Blockanfang) nicht, sieht 
man das anders, musste man bis C99 mit C++ vorlieb nehmen.

von mh (Gast)


Lesenswert?

Ist das "int i" in
Rufus Τ. Firefly schrieb:
> for (int i = 0; i < 7; i++)

nicht auch erst seit c99 legal?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark Brandis schrieb:
> Versteh ich jetzt nicht. C99 ist doch auch ANSI-C. Oder?

Nein. Der ANSI-C-Standard ist von 1989 und wurde nacheinander durch die
ISO-C-Standards von 1990 (mit Ergänzungen von 1994), 1999 und 2011
abgelöst.

Die in diesen vier Standards beschriebenen C-Spezifikationen werden oft
kurz als C89, C90, C99 und C11 bezeichnet. Dabei unterscheidet sich C90
(ISO) nur marginal von C89 (ANSI), weswegen die Bezeichnungen "ANSI-C",
"C89" und "C90" oft synonym verwendet werden.

Mark Brandis schrieb:
> Und wo ist das Problem? Wenn der Code-Checker nach C99 Standard prüft,
> sind // Kommentare selbstverständlich in Ordnung.

Der Code-Checker hat aber nach ANSI bzw. C89 geprüft, weil firmeninterne
Programmierrichtlinien diesen (alten) Standard vorgaben. Deswegen durfte
man keine //-Kommentare benutzen, obwohl sie der verwendete Compiler
ohne jegliche Warnungen akzeptiert hat.

Ich wollte mit dem Beispiel in Reaktion auf Rufus' Beitrag

Rufus Τ. Firefly schrieb:
> Habe mal in alten Sourcen gegraben, und ein 20 jahre altes C-File
> gefunden, in dem ich auch schon Zeilenkommentare genutzt habe.

nur ausdrücken, dass man vorsichtig sein sollte, irgendwelche
Sprachfeatures zu benutzen, die zwar von praktisch allen Compilern
akzeptiert werden, aber nicht offiziell standardisiert sind.

Natürlich ist die Verwendung der //-Kommentare in ANSI-C-Programmen auch
kein großes Missgeschick, da sie ggf. auch nachträglich noch ohne großen
Aufwand in /**/-Kommentare konvertiert werden können.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.