fopen
-
Hallo dieses mal bin ich ganz sicher im richtigen Forum. Es geht um die Funktion
*fopen(const char *filename, const char *mode);Ich habe den filename in einer Variable gespeichert, da ich den Dateinamen von der Standardeingabe einlesen möchte. Ist es denn überhaupt möglich diesen Wert dann an fopen zu übergeben. Ich bräuchte doch quasi eine Stringrepräsentation des char Arrays.
filename geht nicht = Anfangsadresse
*filename geht auch nicht = erster Buchstabe
gibt es eine Funktion die sowas bewerkstelligt. So quasi wie printf aber die Stringrepräsentation nicht an die Standardausgabe sondern als RW den ich in der fopen Funktion benutzen kann. Und wie ist das mit dem const?
-
Lazarus schrieb:
filename geht nicht = Anfangsadresse
Und das ist genau, was du brauchst, also probiers doch einfach mal (ich nehme an, filename ist ein char-Array; ein solches läßt sich implizit in char* konvertieren).
Lazarus schrieb:
Und wie ist das mit dem const?
Das heißt, daß die Funktion dein Array nicht verändert (bzw. nicht verändern sollte; nichts ist unmöglich).
Moritz
-
habe es mit nur filename probiert. Das Programm schluckt das zwar aber es wird keine Datei erstellt sondern das Programm bricht ab. Und auch in dem angegebenen Pfad egal ob mit \ oder mit / geschrieben findet sich keine neue Datei mit dem Namen. Also implizites casting klappt nicht. Explizites casting in der Form (const char*) bringt das gleiche Ergebnis. Und das mit dem const. bist du sicher daß es es nicht bedeutet, daß ein konstanter Wert erwartet wird?
Also ein const Pointer. Weil wenn es doch das bedeutet ist es denke ich nicht ganz unwichtig. Ein Beispiel für die bedeutsame Unterscheidung ist beispielsweise wenn man versucht ein Array zu deklarieren bei dem der Index eine Variable ist. Fehler.Cu
-
Lazarus schrieb:
Explizites casting in der Form (const char*) bringt das gleiche Ergebnis.
Ist klar. Da ist irgendwo anders ein Fehler.
Lazarus schrieb:
Und das mit dem const. bist du sicher daß es es nicht bedeutet, daß ein konstanter Wert erwartet wird?
Ja; das const garantiert dem Benutzer nur, daß der übergebene Wert, also das Array, nicht verändert wird.
Lazarus schrieb:
Ein Beispiel für die bedeutsame Unterscheidung ist beispielsweise wenn man versucht ein Array zu deklarieren bei dem der Index eine Variable ist. Fehler.
Nach C99 müßte das gehen ;).
Poste mal deinen Quelltext!
Moritz
-
Ne der Fehler muss da liegen wenn ich z.B. in die fopen Funktion
"C:/lebenslauf.htm" als erstes Argument schreibe, dann geht alles glatt. Aber wie du magst der Code ist aber nicht allzu kurz. Ist demnächst sowieso auf meiner HP zu sehen.
#include <stdio.h> #include <stdlib.h> #define LENGTH0 10 #define LENGTH1 20 #define LENGTH2 30 #define LENGTH4 70 #define LENGTHMAX 200 #define ITEM2 10 #define ITEM3 20 #define MONTH 3 #define YEAR 5 typedef struct { char sccMonthBeg[MONTH]; char sccYearBeg[YEAR]; char sccMonthEnd[MONTH]; char sccYearEnd[YEAR]; char sccText[LENGTHMAX]; }scItem; void pointerinit(scItem **pArray, int length); void stringinput(char string[],unsigned int length); int main(int argc, char *argv[]) { scItem itemTest; char cBuffer1[MONTH]; char cBuffer2[YEAR]; char cBuffer3[MONTH]; char cBuffer4[YEAR]; char cBuffer5[LENGTHMAX]; scItem **pscItemSchools = NULL; scItem **pscItemEducation = NULL; scItem **pscItemJobs = NULL; const char* pszHtmlHead = "<html>\n<head>\n<title>Lebenslauf</title>\n" "<meta name='description' content='Lebenslauf für' />\n" "<meta name='author' content='Damir Abdijevic' />\n" "<meta name='keywords' content=' ' />\n" "<meta name='date' content='2005-01-23T08:00:00+00:00' />\n" "</head>\n" ; const char* pszTableMargin ="<br>\n<br>\n<br>\n"; const char* pszTableWidth ="100%"; const char* pszh0="Lebenslauf"; const char* pszh1="Angaben zur Person"; const char* pszh2="Schulbildung"; const char* pszh3="Ausbildung"; const char* pszh4="Berufstaetigkeit und Fortbildungen"; const char* pszh5="Kenntnisse und Fertigkeiten"; const char* pszName ="Name :"; const char* pszStreet ="Strasse :"; const char* pszZipCity ="Postleitzahl/Ort:"; const char* pszTelephone ="Telefonnummer :"; const char* pszBirthDate ="Geburtsdatum :"; const char* pszBirthPlace ="Geburtsort :"; const char* pszPstatut ="Familienstand :"; const char* pszCitizen ="Staatsangehoerigkeit :"; const char* pszBegMonth="Geben Sie den Anfangsmonat ein: "; const char* pszBegYear="Geben Sie das Anfangsjahr ein: "; const char* pszEndMonth="Geben Sie den Endmonat ein: "; const char* pszEndYear="Geben Sie das Endjahr ein: "; const char* pszDescription="Geben Sie die Beschreibung ein: "; const char* pszLanguages ="Sprachen (maximal 70 Zeichen): "; const char* pszHobbies ="Hobbies (maximal 70 Zeichen): "; const char* pszSpez="Besondere Interessen(maximal 70 Zeichen): "; char cName[LENGTH1]; char cFirstName[LENGTH1]; char cStreet[LENGTH2]; char cZip[LENGTH0]; char cCity[LENGTH2]; char cTelephone[LENGTH1]; char cBirthDate[LENGTH1]; char cBirthPlace[LENGTH1]; char cPstatut[LENGTH1]; char cCitizen[LENGTH1]; char cLanguages[LENGTH4]; char cHobbies[LENGTH4]; char cSpez[LENGTH4]; char cAbort; char cFile[LENGTH4]; int iCount=0; int iSchCount=0; int iEduCount=0; int iJobCount=0; FILE *fpout1=NULL; printf("%s\n\n",pszh1); printf("Geben Sie Ihren Namen ein:\t\t\t"); fgets(cName,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihren Vornamen ein:\t\t\t"); fgets(cFirstName,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihre Strasse und Hausnummer ein:\t"); fgets(cStreet,LENGTH2,stdin); fflush(stdin); printf("Geben Sie Ihre Postleitzahl ein:\t\t"); fgets(cZip,LENGTH0,stdin); fflush(stdin); printf("Geben Sie Ihren Wohnort/Stadt ein:\t\t"); fgets(cCity,LENGTH2,stdin); fflush(stdin); printf("Geben Sie Ihre Telefonnummer ein:\t\t"); fgets(cTelephone,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihr Geburtsdatum ein:\t\t\t"); fgets(cBirthDate,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihren Geburtsort ein:\t\t\t"); fgets(cBirthPlace,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihren Familienstand ein:\t\t"); fgets(cPstatut,LENGTH1,stdin); fflush(stdin); printf("Geben Sie Ihre Staatsangehoerigkeit ein:\t"); fgets(cCitizen,LENGTH1,stdin); fflush(stdin); printf("Geben Sie den Pfad und Dateinamen ein in dem der Lebenslauf gespreichert werden soll: "); fgets(cFile,LENGTH4,stdin); fflush(stdin); printf("%s",cFile); pscItemSchools = (scItem **)malloc(ITEM2*sizeof(scItem*));//Speicherallocation für Pointer auf Pointer if(pscItemSchools == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(1); } for(iCount=0;iCount<ITEM2;iCount++) { pscItemSchools[iCount] = (scItem*)malloc(1*sizeof(scItem));//Speicherallocation für Pointer if(pscItemSchools[iCount] == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(2); } } pscItemEducation = (scItem **)malloc(ITEM2*sizeof(scItem*)); if(pscItemEducation == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(1); } for(iCount=0;iCount<ITEM2;iCount++) { pscItemEducation[iCount] = (scItem*)malloc(1*sizeof(scItem)); if(pscItemEducation[iCount] == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(2); } } pscItemJobs = (scItem **)malloc(ITEM3*sizeof(scItem*)); if(pscItemJobs == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(1); } for(iCount=0;iCount<ITEM3;iCount++) { pscItemJobs[iCount] = (scItem*)malloc(1*sizeof(scItem)); if(pscItemJobs[iCount] == NULL) { printf("Fehler bei der Speicherallocation! Programm wird abgebrochen\n"); exit(2); } } iCount=0; cAbort='0'; printf("\n\n%s maximal 10 Schulen\nMonatsformat zweistellig, Jahresformat vierstellig\n\n",pszh2); do { printf("%s",pszBegMonth); fgets(cBuffer1,MONTH,stdin); fflush(stdin); printf("%s",pszBegYear); fgets(cBuffer2,YEAR,stdin); fflush(stdin); printf("%s",pszEndMonth); fgets(cBuffer3,MONTH,stdin); fflush(stdin); printf("%s",pszEndYear); fgets(cBuffer4,YEAR,stdin); fflush(stdin); printf("%s",pszDescription); fgets(cBuffer5,LENGTHMAX,stdin); fflush(stdin); strcpy(pscItemSchools[iCount]->sccMonthBeg, cBuffer1); strcpy(pscItemSchools[iCount]->sccYearBeg, cBuffer2); strcpy(pscItemSchools[iCount]->sccMonthEnd, cBuffer3); strcpy(pscItemSchools[iCount]->sccYearEnd, cBuffer4); strcpy(pscItemSchools[iCount]->sccText, cBuffer5); iCount++; iSchCount++; printf("\n\nWeiter? Um eine weitere Schule hinzufuegen druecken Sie die Enter Taste. Um\n" "zu dem Punkt Ausbildungen zu gehen druecken Sie den Buchstaben a und bestaetigen\n" "Sie mit Enter:\n\n"); cAbort=getchar(); } while(iCount<ITEM2 && cAbort!='a'); iCount=0; cAbort='0'; printf("\n\n%s maximal 10 Ausbildungen\nMonatsformat zweistellig, Jahresformat vierstellig\n\n",pszh3); do { printf("%s",pszBegMonth); fflush(stdin); fgets(cBuffer1,MONTH,stdin); printf("%s",pszBegYear); fflush(stdin); fgets(cBuffer2,YEAR,stdin); printf("%s",pszEndMonth); fflush(stdin); fgets(cBuffer3,MONTH,stdin); printf("%s",pszEndYear); fflush(stdin); fgets(cBuffer4,YEAR,stdin); printf("%s",pszDescription); fflush(stdin); fgets(cBuffer5,LENGTHMAX,stdin); strcpy(pscItemEducation[iCount]->sccMonthBeg, cBuffer1); strcpy(pscItemEducation[iCount]->sccYearBeg, cBuffer2); strcpy(pscItemEducation[iCount]->sccMonthEnd, cBuffer3); strcpy(pscItemEducation[iCount]->sccYearEnd, cBuffer4); strcpy(pscItemEducation[iCount]->sccText, cBuffer5); iCount++; iEduCount++; printf("\n\nWeiter? Um eine weitere Ausbildung hinzufuegen druecken Sie die Enter Taste. Um\n" "zu dem Punkt Berufstaetigkeit und Fortbildungen zu gehen druecken\n" "Sie den Buchstaben a und bestaetigen Sie mit Enter:\n\n"); cAbort=getchar(); } while(iCount<ITEM2 && cAbort!='a'); iCount=0; cAbort='0'; printf("\n\n%s maximal 20 Punkte\nMonatsformat zweistellig, Jahresformat vierstellig\n\n",pszh4); do { printf("%s",pszBegMonth); fflush(stdin); fgets(cBuffer1,MONTH,stdin); printf("%s",pszBegYear); fflush(stdin); fgets(cBuffer2,YEAR,stdin); printf("%s",pszEndMonth); fflush(stdin); fgets(cBuffer3,MONTH,stdin); printf("%s",pszEndYear); fflush(stdin); fgets(cBuffer4,YEAR,stdin); printf("%s",pszDescription); fflush(stdin); fgets(cBuffer5,LENGTHMAX,stdin); strcpy(pscItemJobs[iCount]->sccMonthBeg, cBuffer1); strcpy(pscItemJobs[iCount]->sccYearBeg, cBuffer2); strcpy(pscItemJobs[iCount]->sccMonthEnd, cBuffer3); strcpy(pscItemJobs[iCount]->sccYearEnd, cBuffer4); strcpy(pscItemJobs[iCount]->sccText, cBuffer5); iCount++; iJobCount++; printf("\n\nWeiter ? Um eine weitere Berufstaetigkeit hinzufuegen druecken Sie die Enter Taste. Um\nzu " "dem Punkt Berufstaetigkeit und Fortbildungen zu gehen druecken\n" "Sie den Buchstaben a und bestaetigen Sie mit Enter:\n\n"); cAbort=getchar(); } while(iCount<ITEM3 && cAbort!='a'); printf("\n\n%s",pszLanguages); fflush(stdin); fgets(cLanguages,LENGTH4,stdin); printf("\n%s",pszHobbies); fflush(stdin); fgets(cHobbies,LENGTH4,stdin); printf("\n%s",pszSpez); fflush(stdin); fgets(cSpez,LENGTH4,stdin); [b][u]fpout1 = fopen((const char*)cFile,"w");[/u][/b] //wenn ich hier "C:/lebenlauf.htm"reinschreibe funktioniert es if(fpout1==NULL) { fprintf(stderr,"Oeffnen nicht moeglich\n"); return 1; } fputs(pszHtmlHead,fpout1); fprintf(fpout1,"<body style='font-family:Garamond; font-size:11pt'>\n" "<h1 style='text-align:center'>Lebenslauf</h1>\n" "<table width='%s'>\n" "<colgorup>\n" "<col width='2*'>\n" "<col width='4*'>\n" "<col width='2*'>\n" "<colgorup>\n" "<tr>\n" "<td colspan='3'style='background-color:rgb(192,192,192)'><h2>%s</h2></td>\n" "</tr>\n" "<tr>\n" ,pszTableWidth,pszh1); fprintf(fpout1,"<td> %s</td>\n", pszName); fprintf(fpout1,"<td>%s %s </td>\n", cName,cFirstName); fputs("<td rowspan='9'><img src='pic.gif' alt='Bewerbungsbild'</td>\n" "</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszStreet); fprintf(fpout1,"<td> %s </td>\n", cStreet); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszZipCity); fprintf(fpout1,"<td> %s %s</td>\n", cZip,cCity); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszTelephone); fprintf(fpout1,"<td> %s </td>\n", cTelephone); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszBirthDate); fprintf(fpout1,"<td> %s</td>\n", cBirthDate); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszBirthPlace); fprintf(fpout1,"<td> %s</td>\n", cBirthPlace); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszPstatut); fprintf(fpout1,"<td> %s</td>\n", cPstatut); fputs("</tr>\n" "<tr>\n",fpout1); fprintf(fpout1,"<td> %s</td>\n", pszCitizen); fprintf(fpout1,"<td> %s</td>\n", cCitizen); fputs("</tr></table>\n",fpout1); fprintf(fpout1,"%s",pszTableMargin); fprintf(fpout1,"<table width='%s'>\n" "<colgroup>\n" "<col width='1*'>\n" "<col width='5*'>\n" "</colgroup>\n" "<tr>\n" "<td colspan='2'style='background-color:rgb(192,192,192)'><h2>%s</h2></td>\n" "</tr>\n" ,pszTableWidth,pszh2); for(iCount=0;iCount<iSchCount;iCount++) { fprintf(fpout1,"<tr>\n<td>%s/%s - %s/%s</td>\n<td>%s</td>\n</tr>",pscItemSchools[iCount]->sccMonthBeg,pscItemSchools[iCount]->sccYearBeg, pscItemSchools[iCount]->sccMonthEnd,pscItemSchools[iCount]->sccYearEnd,pscItemSchools[iCount]->sccText); } fputs("</table>\n",fpout1); fprintf(fpout1,"%s",pszTableMargin); fprintf(fpout1,"<table width='%s'>\n" "<colgroup>" "<col width='1*'>" "<col width='5*'>" "</colgroup>" "<tr>\n" "<td colspan='2'style='background-color:rgb(192,192,192)'><h2>%s</h2></td>\n" "</tr>\n" ,pszTableWidth,pszh3); for(iCount=0;iCount<iEduCount;iCount++) { fprintf(fpout1,"<tr>\n<td>%s/%s - %s/%s</td>\n<td>%s</td>\n</tr>\n",pscItemEducation[iCount]->sccMonthBeg,pscItemEducation[iCount]->sccYearBeg, pscItemEducation[iCount]->sccMonthEnd,pscItemEducation[iCount]->sccYearEnd,pscItemEducation[iCount]->sccText); } fputs("</table>\n",fpout1); fprintf(fpout1,"%s",pszTableMargin); fprintf(fpout1,"<table width='%s'>\n" "<colgroup>" "<col width='1*'>" "<col width='5*'>" "</colgroup>" "<tr>\n" "<td colspan='2'style='background-color:rgb(192,192,192)'><h2>%s</h2></td>\n" "</tr>\n" ,pszTableWidth,pszh4); for(iCount=0;iCount<iJobCount;iCount++) { fprintf(fpout1,"<tr>\n<td>%s/%s - %s/%s</td>\n<td>%s</td>\n</tr>\n",pscItemJobs[iCount]->sccMonthBeg,pscItemJobs[iCount]->sccYearBeg, pscItemJobs[iCount]->sccMonthEnd,pscItemJobs[iCount]->sccYearEnd,pscItemJobs[iCount]->sccText); } fputs("</table>\n",fpout1); fprintf(fpout1,"%s",pszTableMargin); fprintf(fpout1,"<table width='%s'>\n" "<colgroup>" "<col width='1*'>" "<col width='5*'>" "</colgroup>" "<tr>\n" "<td colspan='2'style='background-color:rgb(192,192,192)'><h2>%s</h2></td>\n" "</tr>\n" ,pszTableWidth,pszh5); fprintf(fpout1,"<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n",pszLanguages,cLanguages); fprintf(fpout1,"<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n",pszHobbies,cHobbies); fprintf(fpout1,"<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n",pszSpez,cSpez); fputs("</table></body>\n" "</html>\n" ,fpout1); for(iCount=0;iCount<ITEM2;iCount++) { free(pscItemSchools[iCount]); } free(pscItemSchools); for(iCount=0;iCount<ITEM2;iCount++) { free(pscItemEducation[iCount]); } free(pscItemEducation); for(iCount=0;iCount<ITEM3;iCount++) { free(pscItemJobs[iCount]); } free(pscItemJobs); fclose(fpout1); printf("\nIhr Lebenslauf wurde erstellt und unter %s abgespeichert\n\n",cFile); system("PAUSE"); return 0; } //noch Routine einbauen um Datei wählen zu können
-
Lazarus schrieb:
Aber wie du magst der Code ist aber nicht allzu kurz. Ist demnächst sowieso auf meiner HP zu sehen.
Aber bitte nicht so
1.) Du solltest bei dem malloc-Aufruf nicht casten
2.) Dein Code verursacht memory leaks
3.) Sollte eine Funktion nicht aus 500 Zeilen bestehen - also etwas kürzen und lieber auslagern. Dann bleibt es auch übersichtlicher.
4.) Wenn du als Pfad z.B. "C:\temp\tmpdat" angeben willst, solltest du das in c via "C:\\temp\\tmpdat" machen (Stichwort Escapesequenzen)Ist jetzt das war mir sofort aufgefallen ist. Habe es mir nicht zu sehr angesehen
So long
-
[OK, ich verkneifs mir mal, das zu quoten ;)]
Nur die Speicherroutine hätte auch gereicht
Ich bin mal mit dem Debugger durchgestiegen und habe festgestellt, daß bei cFile hinten ein Newline-Zeichen ('\n') dranhängt. Wenn du das entfernst, funktioniert es.Moritz
-
[quote="guard"]
Lazarus schrieb:
Aber wie du magst der Code ist aber nicht allzu kurz. Ist demnächst sowieso auf meiner HP zu sehen.
Aber bitte nicht so
1.) Du solltest bei dem malloc-Aufruf nicht casten
2.) Dein Code verursacht memory leaksWarum soll ich nicht casten? In meinem Buch steht immer schön casten. Wo sollen denn die Memory leaks sein. Der Code der wird noch überarbeitet und dann später auseinander genommen. Ich finde es in der Entwicklungsphase tausend mal unübersichtlicher und anstengender zwischen mehren Files hin und her zu springen und 4 oder 5 unterfenster offen zu haben.
-
[quote="audacia"][OK, ich verkneifs mir mal, das zu quoten ;)]
cFile hinten ein Newline-Zeichen ('\n') dranhängt. Wenn du das entfernst, funktioniert es.
Das mit dem new Line zeichen ist total merkwürdig. Ich habe gelesen, daß fgets ein ein \n im Puffer ablegt. Aber ich dachte damit ist der Tastaturpuffer gemeint. Ich habe andauernd damit das problem daß ich bei eingelesenen Strings dieses \n anstatt der terminierenden null habe.
Weißt du woran es liegen könnte?
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>typedef char** stringArray;
stringArray MallocStringArray(size_t SizeOfOneString, size_t StringCount)
{
char** t=malloc(StringCount*sizeof(char*));
size_t i;
for(i=0;i<StringCount;++i)
t[i]=malloc(SizeOfOneString);
return t;
}void FreeStringArray(stringArray StringArray, size_t StringCount)
{
size_t i;
for(i=0;i<StringCount;++i)
free(StringArray[i]);
free(StringArray);
}bis auf das weggelassene casting sehe ich bei dieser Routine nicht allzuviele Unterschiede zu meiner. Darum ist mir etwas schleierhaft wo die leaks sein sollen
So nun hab ich auch debuggt. Und ich habe sowohl die Anfansadressen bei der Speicherallocation von ** und den einzelnen * verglichen bei der allocation und vor der Freigabe. Die Adressen sind immer die gleichen. Ich habe ja nirgendwo mit Pointeraritmetik ++ oder -- gearbeitet. Bei dem Aufruf von free ist in den Pointern die anfangsadresse des allocierten Speichers drin. Darum glaub ich nicht daß ich nein ich meine mein Programm Speicherlücken macht.