Hallo,
ich arbeite schon ein paar Wochen mit der Lib von Roland Riegel, bisher
habe ich für alle Probleme Threads gefunden, die mir geholfen haben,
aber diesmal nicht.
Wenn ich eine Datei erstelle muss ich den Dateinamen als ein const char
übergeben
Ich möchte den Dateinamen hochzählen lassen.
Name_0
Name_1
Name_2...
Mit den Funktionen itoa, strcpy und strcat komme ich auch zu einen char,
der den gewünschten Dateinnamen enthält.
Weil der Übergabeparameter aber ein const char ist bekomme ich meinen
Dateinamen (Name_0,...) nicht in den const char.
Laut Google gibt es wohl noch const_cast aber das nur für C++. Ich
programmiere in C.
Ich bin doch bestimmt nicht die erste, die mit der Lib von Roland Riegel
fortlaufende Dateinamen erstellen möchte. Wie habt ihr das gelöst?
Ich hoffe Ihr könnt mir helfen.
Gruß
Anna
Anna schrieb:> Mit den Funktionen itoa, strcpy und strcat komme ich auch zu einen char,> der den gewünschten Dateinnamen enthält.> Weil der Übergabeparameter aber ein const char ist bekomme ich meinen> Dateinamen (Name_0,...) nicht in den const char.
dann zeig mal wie du es gemacht hast, denn ein char* kann immer in ein
const char* verwandlet werden.
Anna schrieb:> const char* file
Das bedeutet nur, dass der Inhalt vom String, worauf file zeigt, von
der Funktion nicht geändert wird.
> Ich programmiere in C.
Und welchen Fehler bekommst du? Wie sieht deine Deklaration und wie
sieht deine funktion aus?
Anna schrieb:> Weil der Übergabeparameter aber ein const char ist bekomme ich meinen> Dateinamen (Name_0,...) nicht in den const char.
Warum nicht? Welche Fehlermeldung kommt denn?
> Laut Google gibt es wohl noch const_cast aber das nur für C++.
Das ist für die umgekehrte Richtung, also wenn man ein const wegcasten
möchte.
Der Autor wird sich bei dem const was gedacht haben, deswegen würde ich
das ungern einfach weglassen.
Mein Code
1
intmain(void)
2
{
3
uint8_ta=1;
4
chardateiname[6]="Name_";
5
chardn_hochzaehlen[4];
6
7
constcharfilename[11];
8
9
itoa(a,dn_hochzaehlen,10);
10
strcpy(filename,dateiname);
11
strcat(filename,dn_hochzaehlen);
12
13
}
a ist die Variable die ich hochzählen lassen möchte. das hochzählen ist
hier nicht mit dabei.
Fehler:
strcpy und strcat meckern, dass statt einem "char*" ein "const char*"
kommt
Laut Bib sind beide Funktionen so definiert:
1
externchar*strcpy(char*,constchar*);
2
externchar*strcat(char*,constchar*);
Lasse ich bei Varibale
1
constcharfilename[11];
das const weg funktioniert es.
Es ist auch logisch, dass es nicht funktioniert. Ein const char sollte
nunmal konstant sein und sich nicht verändenr lassen. Ich würde nur
ungern alle Dateinamen per hand eingeben.
Gruß
Anna
> das const weg funktioniert es.
Dann lass es so. Ob die Funktion jetzt einen char oder einen const char
will ist egal, notfalls wird halt automatisch konvertiert (char -->const
char).
Anna schrieb:> Lasse ich bei Varibale> const char filename[11];> das const weg funktioniert es.
Dann lass es weg, denn der filename ist nicht konstant!
Du bastelst ja dran herum (fortlaufende Nummer)... :-o
Also:
Einer Funktion, die "const char*" erwartet, kann man sowohl "const
char*" als auch "char*" übergeben.
Beides ist vollkommen legal und provoziert keine Warnungen.
Das "const" bedeutet hier nur, daß die Funktion das Argument nicht
verändert.
Andererseits kann man einer Funktion, die "char *" erwartet, nicht
"const char*" übergeben.
Das nämlich ist nicht zulässig und wird mit entsprechenden
Fehlermeldungen quittiert.
Das Nichtvorhandensein von "const" bedeutet hier, daß die Funktion das
Argument verändern kann.
Also weglassen funktioniert nicht einfach so. dann bekomme ich den
Fehler, dass fat_create_file ein "char*" erwartet aber ein "const char*"
bekommt. Das muss ich jetzt nicht verstehen:)
Danke für die Antworten, besonders von Rufus. Ich werde mich nochmal
genauer mit dem const beschäftigen (bin ja noch Anfänger:) )und mich bei
Fragen nochnal melden.
So nochmal Danke.
Es funktioniert wenn ich bei der Deklaration des "filename" das const
einfach wegglassen wie mehrere geschrieben haben.
Ich habe die DEfinition von const wohl missverstanden.
In diese Richtung char* --> const char* darf man ruhig casten.
Einfach immer vor Augen halten, was der Compiler/Linker damit macht.
- "Deklaration mit const" --> Flash
--> nicht (ohne weiteres) veränderbar.
- "Deklaration ohne const" --> RAM
--> veränderbar.
Lustig wird's dann erst, wenn das const nicht ganz vorne steht...
Martin H. schrieb:> Deine Lib erwartet allerdings einen konstanten String, also
casten:fat_create_file(&parent, (const char*) filename, &dir_entry);
> In diese Richtung char* --> const char* darf man ruhig casten.
darf ja, aber man muss nicht. Das macht der compiler schon selber. Der
Cast ist nicht notwendig und sogar fehlerhaft wenn sich mal der type von
filename ändert. (z.b. Wchar)
Martin H. schrieb:> Einfach immer vor Augen halten, was der Compiler/Linker damit macht.> - "Deklaration mit const" --> Flash> --> nicht (ohne weiteres) veränderbar.> - "Deklaration ohne const" --> RAM> --> veränderbar.
Naja, gerade beim hier so beliebten AVR ist das nicht so, da muss man
erheblichen Aufwand treiben, um was ins Flash zu bekommen, ohne daß es
im RAM gespiegelt wird.
Martin H. schrieb:> Deine Lib erwartet allerdings einen konstanten String
NEIN!
Bitte, bitte, bitte.
Lernt mit const umzugehen.
Das const an dieser Stelle
bedeutet:
Junge, ich will von dir an dieser Stelle einen Pointer auf Charcater
haben. Aber: Ich mache dir die Zusicherung, dass ich diese Character als
nicht veränderlich ansehe. Das heißt: ich werde mich nicht an den
Charactern vergreifen und sie verändern. Du kannst also von der Annahme
ausgehen, was immer mir du mir hier als String fütterst, der String wird
nach dem Funktionsaufruf immer noch der gleiche sein wie vorher. Ich
werde noch nicht einmal den Versuch einer Änderung unternehmen. Das
heißt: ich werde auch nicht hergehen und den String mal kurz verändern
und dann wieder in die Ursprungszustand zurückversetzen. Ich benutze den
String wirklich und in jedem einzelnen Fall nur lesend.
Das ist die Bedeutung von const an dieser Stelle:
Die Funktion macht eine Zusicherung!
Und das ist immer so in Argumentlisten: Mit einem const macht die
Funktion eine Zusage an den Aufrufer: Ich werde das Angegebene nicht
verändern.
Ein const in einer Arumgentliste fordert niemals eine Eigenschaft vom
Aufrufer ein, sondern die Funktion sichert damit eine bestimmtes
Verhalten zu!
Und daher ist es völlig legitim, wenn ich an dieser Stelle der Funktion
ein char Array übergebe. Denn die Funktion versucht nicht das Argument
zu verändern. Es ist auch völlig legitim, wenn ich an dieser Stelle ein
Stringliteral angebe. Denn auch hier: Die Funktion versucht nicht den
String zu verändern.
char fileName[20];
...
fat_create_file(..., fileName, ... );
ist also gültig.
Aber auch
fat_create_file(..., "meinFile.txt", ... );
ist gültig.
Wenn die Funktion, die Zusicherung nicht machen würde:
nämlich nicht zulässig! Das es das trotzdem ist, liegt nicht an Logik,
sondern daran, dass dafür in C bei der Einführung von const explizit
eine Ausnahme für char* - const char* zugelassen wurde.
Das ganze ist ein bischen wie:
Mein Kumpel sichert mir zu, dass er in dem Buch dass ich ihm leihe,
nicht herumkritzeln wird.
Also kann ich ihm bedenkenlos sowohl mein Malbuch als auch meine
Gutenbergbibel geben. Bei meinem Malbuch ist es mir egal, ob er drinn
rumkritzelt, bei der Gutenbergbibel aber nicht.
Macht er mir aber diese Zusicherung nicht, dass er das Buch als const
betrachten wird, dann werd ich einen Teufel tun und ihm die
Guttenbergbibel geben.
Anna schrieb:> So nochmal Danke.>> Es funktioniert wenn ich bei der Deklaration des "filename" das const> einfach wegglassen wie mehrere geschrieben haben.>> Ich habe die DEfinition von const wohl missverstanden.
Ja. Bei einem const char* bedeutet das const erstmal nur, daß über
diesen Zeiger der Wert nicht verändert wird. Es bedeutet nicht, daß
der Wert ursprünglich schon konstant sein muß.
Martin H. schrieb:> Nachdem Dein Dateiname nicht konstant ist ("raufzählen"), darf er auch> nicht const deklariert werden:char* filename[11];
Richtig.
> Deine Lib erwartet allerdings einen konstanten String, also casten:
Unsinn. Ein cast ist da völlig überflüssig.
Ich hatte const auch so verstanden, dass meine Funktion einen
konstanten/nicht veränderlichen char möchte.
Nach den teils sehr eindrucksvollen Erklärungen bin ich wieder mal ein
ganzes Stückchen schlauer:)
Der Fairness halber muss man auch sagen, dass es AVR-Compiler gibt, die
ihr eigenes Süppchen mit 'const' kochen. Und das ist schade, denn es
bedeutet, dass sie damit in diesem Punkt ein vom C-Standard abweichendes
Verhalten haben.
Besser wäre es gewesen, wenn sie für die angestrebte Funktionalität
einen eigenen Modifier, zb ala 'flash' oder 'rom' eingeführt hätten. So
aber, und das muss man leider so nennen, haben sie aus keinem guten
Grund heraus eine ganz klare Fehlentscheidung getroffen.