Forum: Mikrocontroller und Digitale Elektronik [C] Int in Datei schreiben


von Christian Q. (osx)


Lesenswert?

Hallo, ich habe ein Problem mit den Datentypen int und char in 
Verbindung zu arbeiten.
Ich versuche Zahlen in eine Datei zu schreiben und benutze dafür
int fprintf(FILE *stream, const char *format);

Problem ist nun, dass die Funktionen einen const char* braucht.
Hier also mein Ansatz.
1
#include <stdio.h>
2
3
FILE* resultfile;
4
int size;
5
char* psize;
6
7
8
int main (int argc, const char * argv[]) {
9
  
10
  resultfile = fopen( "out.txt", "r" );
11
  if(resultfile == NULL) {
12
    printf("Fehler beim oeffnen\n");
13
  } else {
14
    printf("ok");
15
    resultfile = fopen( "out.txt", "w" );
16
    
17
    
18
    size = 7;
19
    psize = &size; //warning: assignment from incompatible pointer type
20
    fprintf(resultfile, *psize); //warning: passing argument 2 of 'fprintf' makes pointer from integer without a cast
21
        
22
    
23
  }
24
25
  
26
    
27
  fclose(resultfile);
28
  return 0;
29
}

Das ganze endet aber in Warnungen und ich hab keine Ahnung wie man das 
lösen muss.
Ich hoffe jemand kann mir das erklären.

von Peter II (Gast)


Lesenswert?

wie sollen denn die Zahlen in der Datei stehen, binär oder als Text?

von Karl H. (kbuchegg)


Lesenswert?

Christian Q. schrieb:

> Ich versuche Zahlen in eine Datei zu schreiben und benutze dafür
> int fprintf(FILE *stream, const char *format);
>
> Problem ist nun, dass die Funktionen einen const char* braucht.

fprintf funktioniert wie printf, nur dass es in eine Datei schreibt.

drumm steckt ja auch "printf" im Namen drinnen

   printf          Ausgabe auf die Standardausgabe
   sprintf         wie printf, nur wird das Ergebnis in einem String
                   abgelegt
   fptintf         wie printf, nur wird das Ergebnis auf einen andern
                   Stream als die Stanardausgabe geschickt.

Der const char* ist an dieser Stelle einfach nur der Formatstring, so 
wie er auch bei printf eingesetzt wird

   fprintf( resultfile, "Hallo World\n" );
   fprintf( resultfile, "Ergebnis: %d\n", size );
   ...

> Das ganze endet aber in Warnungen und ich hab keine Ahnung wie man das
> lösen muss.

Dein Problem ist, dass du kein C-Buch hast.
Da stehen solche Sachen, und noch viele viele mehr, in langen Kapiteln 
drinnen, in denen einem das alles haarklein erklärt wird.

von Christian Q. (osx)


Lesenswert?

Peter II schrieb:
> wie sollen denn die Zahlen in der Datei stehen, binär oder als Text?

Wo ist da der Unterschied?
1
resultfile = fopen( "out.txt", "w" );
2
size = 7;
3
fprintf(resultfile, "%d", size);
Warum darf ich size mitgeben? (int)
Es benötigt doch einen char* ?

von DirkB (Gast)


Lesenswert?

Der char* ist das "%d". (In diesem Fall ein Stringliteral)
Das ist der Formatstring. Dort steht drin wie die Parameter ausgegeben 
werden.
%d bedeutet Integer als vorzeichenbehaftete Dezimalzahl.
Und dann müssen noch die PaTramter mit angegeben werden.

Schau mal bei 
http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/

von Karl H. (kbuchegg)


Lesenswert?

Christian Q. schrieb:

>
1
> resultfile = fopen( "out.txt", "w" );
2
> size = 7;
3
> fprintf(resultfile, "%d", size);
4
>
> Warum darf ich size mitgeben? (int)
> Es benötigt doch einen char* ?


Darf ich vorschlagen, dass du ehe du dich mit Dateien beschäftigst erst 
mal die offenbar übersprungenen 15 Kapitel, die vorher in deinem C-Buch 
stehen (welches du möglicherweise erst kaufen musst) nachholst.

printf ist 1. Stunde C-Programmierung, 1. Lektion.
Gleich nachdem man gelernt hat, dass in C ein komplettes Programm immer 
eine main() Funktion haben muss, weil dort die Programmausführung 
anfängt, geht es mit printf und seinem Formatstring los.

von Karl H. (kbuchegg)


Lesenswert?

Du benutzt im übrigen ganz sicher nicht
1
int fprintf(FILE *stream, const char *format);
sondern du benutzt
1
int fprintf(FILE *stream, const char *format, ...);
und das ist eine andere Geschichte. fprintf ist nämlich, genauso wie 
printf oder sprintf, eine variadische Funktion.

von Christian Q. (osx)


Lesenswert?

Meine Frage war speziell warum man einen int mitgeben kann. Was der 
Hintergrund mit den Pointern ist. Nur weil ich frag warum das bei der 
Funktion so funktioniert wird das gerade so hingestellt, als hätte ich 
die Funktion noch nie benutzt.

von Karl H. (kbuchegg)


Lesenswert?

Christian Q. schrieb:
> Meine Frage war speziell warum man einen int mitgeben kann. Was der
> Hintergrund mit den Pointern ist.

Welchen Teil der ANtwort
"Der Pointer bezieht sich auf den Format-STRING" verstehst du nicht?

> Nur weil ich frag warum das bei der
> Funktion so funktioniert wird das gerade so hingestellt, als hätte ich
> die Funktion noch nie benutzt.

Es sieht aber ganz danach aus, als ob du noch nie printf benutzt hättest

1
#include <stdio.h>
2
3
int main()
4
{
5
  int i;
6
7
  for( i = 0; i < 10; ++i )
8
    printf( "d: %d\n", i, i*i );
9
}

und was ist da jetzt so schwierig drann, dass fprintf wie printf 
funktioniert, nur dass vor den Formatstring noch der FILE-Pointer 
eingefügt wird, um zu spezifizieren, wo die Ausgabe hingeroutet werden 
soll.

Glaub nicht, dass ich an der Art der Fragestellung nicht erkennen kann, 
wie weit du mit deinen C-Studien bist.

von Christian Q. (osx)


Lesenswert?

Du verstehst mich einfach nicht.
Wie ich fprintf benutzen muss hab ich hier schon erkannt (paar Beiträge 
drüber), nachdem ihr mich freundlich darauf hingewiesen habt, dass man 
es wie printf benutzt:
> resultfile = fopen( "out.txt", "w" );
> size = 7;
> fprintf(resultfile, "%d", size);

Mir geht es darum wie es sein kann, dass die Funktion einen char* haben 
möchte, ich ihr aber einen int (einen >int<) übergebe und das sogar kein 
Problem ist.

ich kann mir doch auch nicht einfach eine Funktion bauen:

void bla(const char* st) {

}
und sie mit bla(2) aufrufen.

von Peter II (Gast)


Lesenswert?

Christian Q. schrieb:
> ich kann mir doch auch nicht einfach eine Funktion bauen:
>
> void bla(const char* st) {
>
> }
> und sie mit bla(2) aufrufen.

kannst du? Schon mal getestet?

von Karl H. (kbuchegg)


Lesenswert?

Christian Q. schrieb:
> Du verstehst mich einfach nicht.
> Wie ich fprintf benutzen muss hab ich hier schon erkannt (paar Beiträge
> drüber), nachdem ihr mich freundlich darauf hingewiesen habt, dass man
> es wie printf benutzt:
>> resultfile = fopen( "out.txt", "w" );
>> size = 7;
>> fprintf(resultfile, "%d", size);
>
> Mir geht es darum wie es sein kann, dass die Funktion einen char* haben
> möchte, ich ihr aber einen int (einen >int<) übergebe und das sogar kein
> Problem ist.

Zähl doch mal die Argumente und bring sie zur Übereinstimmung! Wer ist 
wer?

int fprintf(FILE *stream, const char *format, ...);

                ^               ^              ^
                |               |              |
                v               v              v

    fprintf(resultfile,       "%d",            size);


> und sie mit bla(2) aufrufen.

tust du doch gar nicht!
Der Formatstring ist das, was an den const char* gebunden wird. Alles 
was danach kommt wird vom ... aufgenommen. Variadische Funktion eben.

Ist doch bei printf auch nicht anders!

int printf( const char* format, ... );

   printf( "%d: %d\n", i, i*i );

der Formatstring "%d: %d\n" ist das erste Argument, welches als "const 
char*" erwartet wird. Alles danach fällt unter die Ellipsis ...


Und nein: die ... sind jetzt kein textueller Kunstgriff von mir um mir 
Schreibarbeit zu ersparen. Das ist ein C Syntax-Konstrukt! Es bedeutet 
soviel wie: Lieber Compiler, da können jetzt noch Funktionsargumente 
kommen, über die man aber nichts näheres aussagen kann. Die Funktion 
weiß aber schon, wie sie deren Typ erkennen wird (in diesem Fall: indem 
sie den Formatstring auseinandernimmt)

Genau deswegen kann man bei printf in einer Ausgabe beliebig viele 
Argumente ausgeben. Es muss nur jeweils einen dazu passenden, korrekten 
%-Eintrag im Formatstring geben, damit die Funktion selber sich darum 
kümmern kann, die Argumente mit ihren richtigen Datentypen zu 
organsieren.

Und bei fprintf ist das völlig identisch.

von Christian Q. (osx)


Lesenswert?

Peter II schrieb:
> Christian Q. schrieb:
>> ich kann mir doch auch nicht einfach eine Funktion bauen:
>>
>> void bla(const char* st) {
>>
>> }
>> und sie mit bla(2) aufrufen.
>
> kannst du? Schon mal getestet?

bla makes pointer from integer without cast


Jetzt hab ichs .. Hab die ganze Zeit den char* dem übergabewert size 
zugeordnet. Hab mich irgendwie verguckt..

von Lars (Gast) (Gast)


Lesenswert?

Ich muss hier auch mal meinen Senf zu dem allgemeinem Problem des "sich 
nicht selbst Informierens" abgeben.

Es ist toll, dass man hier wirklich ernstgemeinte und konkret 
formulierte Fragen stellen kann und auch oft ausführliche und genauso 
ernstgemeinte  Antworten erhält. Schön, dass es dieses Forum gibt.

Als frech möchte ich es jedoch bezeichnen, wenn Leute hier Fragen 
stellen die offenbar zur Grundlage gehören und deren Antwort sich jeder 
er-google-n kann oder bei Wiki nachschlagen kann.

Wie viele Stunden/Tage verbringt ein wirklich begeisterter Bastler (und 
ich zähle mich da auch ein bisschen dazu) mit Literaturstudium (z.B. 
Bücher oder Datenblätter) um grundlegende und auch komplexe spezielle 
Probleme zu ergründen.

Deshalb sehe ich es nicht ein warum teils simple Fragen - wo man sich 
schon beim ersten Satz fragt, warum macht ER dieses Hobby wenn er DAS 
nicht weiß - gestellt werden.

Einige von Euch boykottieren ja dankenswerterweise die Beantwortung 
solcher Fragen. Auch wenn es auf den ersten Blick unfreundlich 
erscheinen mag. Aber man gibt sein mühsam erworbenes Wissen nicht 
einfach so preis.

Das Wort „Studium“ kommt aus dem lateinischem „studere“ und
heißt : sich (um etwas) bemühen !

Also an alle Fragensteller: bemüht euch erstmal euer Problem in den 
Grundlagen selbst zu erforschen.
Wenn dann noch ganz kontrete Fragen bleiben sind sicher alle gern bereit 
zu helfen, aber eben nicht die Grundlagen zu erklären. Dafür gibt es 
Bücher und informative Internet-Artikel.

von Christian Q. (osx)


Lesenswert?

Meinst du ich hab vorher nicht google bemüht?
Wenn man sich mit einem Thema auseinander setzt und letzendlich gut 
darin ist fällt es einem leicht abzugrenzen in welcher Reihenfolge man 
wohl am besten gelernt hätte. Aber solang man das nicht ist irrt man ein 
wenig rum .. man hat diese Funktion schonmal gehört .. da mal was 
gelesen.
Wenn man das sein ganzes Halbwissen dann zusammenbaut verschwimmen die 
Grenzen von "Bekannten" und "Neuen" - aber irgendwo muss man sich ja an 
neues Herantasten.

Wenn man dann hier als erfahrener Programmierer z.B. meine Beitrag liest 
knallem einen gleich 4 Funktionen und 1 Snippet durch den Kopf und man 
fragt sich "wo ist sein Problem?". Versetzt man sich jetzt aber mal in 
die Lage des anderen: Der weiß so ungefähr was es machen will. Er kennt 
nicht alle Funktionen, er kennt die Vorteile zwischen dieser und der 
anderen Funktion nicht. Das sind alles Erfahrungen die man sammelt und 
ein Anfänger nicht berücksichtigen kann.

Schlussendlich, wenn man weiß wie es geht und in welchem Context man 
suchen muss sagt man sich dann auch "ups was hab ich denn da gemacht".

von gaast (Gast)


Lesenswert?

Christian Q. schrieb:
> Wenn man das sein ganzes Halbwissen dann zusammenbaut verschwimmen die
> Grenzen von "Bekannten" und "Neuen" - aber irgendwo muss man sich ja an
> neues Herantasten.

Wie wäre es mit dem schon so oft empfohlenen guten Buch, in dem das 
alles erklärt wird?

von Karl H. (kbuchegg)


Lesenswert?

Christian Q. schrieb:

> Wenn man das sein ganzes Halbwissen

Genau das ist das Stichwort: Halbwissen.

Ohne systematische Herangehensweise vom Einfachen zum Schwierigen wirst 
du immer beim Halbwissen bleiben. Du kannst es drehen wie du willst, ich 
hab noch nie ein Online-Tutorial gesehen, dass es mit einem gut 
gemachten Buch aufnehmen kann. Ganz im Gegenteil: In vielen 
Online-Tutorien finden sich haarsträubende Fehler. Noch öfter werden 
wichtige Dinge der Kürze geopfert und ganz einfach weggelassen. Es hat 
schon seinen Grund warum ein C Buch nicht unter 150 Seiten wegkommt und 
ein Online Tutorial selten mehr als 20 Seiten umfasst.

Google ist gut, wenn einem mal die Details entfallen sind und man 
schnell die Doku zu einer Funktion braucht. Aber um damit bei 0 
beginnend einzusteigen ist das nicht geeignet.

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.