2017-04-24 6 views
0

Es ist mir nicht klar, was mit meinem Programm nicht stimmt, es ist ein einfacher Code, um eine Datei zu öffnen, die erste Zeile daraus zu lesen und dann auszudrucken. Aber das Programm stürzt ständig ab. Der eigentliche Inhalt meiner Textdatei ist ein Satz: Testen Sie meinen Code.Es ist nicht möglich, einen char * String zu drucken

int main(void) 
{ 
FILE *stream; 
char *s; 
stream = fopen("input.txt", "r"); 
fscanf(stream, " %s", &s); 

printf("%s", s); 


fclose(stream); 
return 0; 
} 

ich angewiesen bin nicht die Bibliotheksfunktionen in <string.h>

+3

1. Sie überprüfen nicht das Ergebnis von 'fopen'. 2. 's' ist ein nicht initialisierter Zeiger - Wohin mit den Daten? – John3136

+1

'Zeichen s [16]; fgets (s, sizeof s, stream); 'anstelle von' char * s; ... fscanf (stream, "% s", &s); ' – BLUEPIXY

+1

Wenn du GCC verwendest, kompiliere immer mit' gcc -Wall -Werror' . –

Antwort

3

s gefunden zu verwenden, ist eine nicht initialisierte Zeiger. Sie müssen etwas Speicherplatz für fscanf reservieren, in den Sie schreiben können.

+0

Ich initialisierte es als: char * s = NULL; aber das Programm stürzt immer noch – user43783

+0

ab Das bietet keinen Speicher zum Beschreiben. – aschepler

+0

Sie können entweder Speicher auf dem Stapel verwenden ('char s [10]' weist 10 Zeichen auf dem Stapel zu) oder verwenden Sie die dynamische Speicherzuweisung mit malloc. – d3L

0

In Ihrem Code fehlen einige Dinge.

// Uninitialise pointer, you need to allocate memory dynamically with malloc before you use it. That is 
char *s; 
int size = 20; // size of the string you want 
s = malloc(size * sizeof(char)); 

// Or you can use a VLA and with this you don't have to use free(s) 

char s[20]; 


// fopen could fail, always check the return value before using it. 
stream = fopen("input.txt", "r"); 

if(stream == NULL){ 
    perror("File opening failed"); 
     return EXIT_FAILURE; 
} 
fscanf(stream, "%s", s); 


//Don't forget to do free(s) to free memory allocated with malloc . when you are done with it 
0
char *s; 

Ordnet die Anzahl von Bytes zum Halten einer Speicheradresse (auf den meisten Systemen 32/64 Bits) benötigt. Aber da Sie den Zeiger nicht initialisieren, ist sein Wert (die Adresse Punkte zu) nicht definiert.

Ergo: fscanf versucht, auf eine nicht definierte Speicheradresse zu schreiben.

Ich initialisierte es als char * s = NULL;

Ja, der Zeiger ist nun initialisiert (yay!), Zeigt aber jetzt auf nichts.

Ergo: fscanf wird versuchen, zu nichts zu schreiben.

Die Lösung ist es, etwas Speicher zu reservieren, den fscanf verwenden kann. fscanf reserviert nicht magisch Speicher für Sie!

Sie können entweder Stapelspeicher oder dynamisch zugewiesenen Speicher (Heap) verwenden.

Stapelspeicher ist einfacher zu verwalten, ist aber viel kleiner als der Heapspeicher.

Hier ist eine Lösung, die Speicher auf dem Stapel verwendet:

// Allocates 10 bytes on the stack 
// Given 1 Character = 1 Byte the 
// buffer can hold up to 9 characters. 
char myBuffer[10]; 

// Initialize s with the address of myBuffer 
char *s = myBuffer; 

// Call fscanf 
fscanf(stream, "%9s", s); 

Sie werden sich vielleicht fragen, warum ich %9s statt %s verwendet.

Der Grund ist, einen Pufferüberlauf zu verhindern:

fscanf nicht weiß, wie groß der Puffer ist, so müssen Sie es sagen.

Andernfalls schreibt fscanf Daten über Ihren zugewiesenen Speicher hinaus.

Ich schlage vor, Sie lesen C-Strings und Speicherverwaltung im Allgemeinen.

+1

'fscanf (stream," % 9s ", s);' liest keine _Linie_ der Eingangsquelle. '% S' speichert keinen Leerraum. Eine Zeile wie' "1 2 3" 'wird nicht in' s' als "1" eingelesen 2 3 "' – chux

+0

@chux Ordentliche Beobachtung. Wusste das nicht :) – d3L

Verwandte Themen