2016-06-22 11 views
-2

Ich habe eine Datei, die wie folgt aussieht:malloc für char Zeiger und printf

ATOM   HIS 
ATOM   TRP 
ATOM   PHE 

ich die erste Spalte ausdrucken möchten, finden Sie meine C-Code:

#include<stdio.h> 
#includ<stdlib.h> 
void main 
{ 
    FILE *fp; 
    fp=fopen("xyz","r"); 
    char *atm,*res; 
    char buff[200]; 
    while(fgets(buff,sizeof (buff),fp)!=NULL){ 
        i++; 
    } 
    rewind(fp); 
    atm=(char*)malloc(i * sizeof (char*)); 
    res=(char*)malloc(i * sizeof (char*)); 
    while(fgets(buff,sizeof (buff),fp)!=NULL){ 
       fscanf(fp,"%s %s",&atm[i],&res[i]); 
       i++; 
    } 
    for(j=0;j<i;j++){ 
      printf("%s\n",atm); 
    } 

Ich würde erwarten, die folgende Ausgabe:

ATOM 
ATOM 
ATOM 

Aber es nicht kompiliert und sagt, dass:

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ 

daher in printf Aussage habe ich &-atm (das heißt & atm statt atm) hinzugefügt. In diesem Fall stellt der Code gut, aber gibt die folgende Ausgabe:

AAAAAAAAAAAAAAAATOM AAAAAAAAAATOM AAAAAAAATOM

Ich werde es begrüßen jeden Vorschlag in Bezug auf diese.

+0

[Bitte lesen Sie diese Diskussion darüber, warum nicht der Rückgabewert von 'malloc()' und Familie in 'C' umgewandelt werden soll. (Http://stackoverflow.com/q/605845/2173917). –

+0

Kann das nicht kompilieren. – BLUEPIXY

+0

Sie reservieren (malloc) Platz für einen Char-Zeiger, warum? – tkausl

Antwort

1

Zunächst einmal

atm=(char*)malloc(sizeof (char*)); 

nicht tut, was Sie denken, es tut. Es reserviert nur einen Speicher genug, um eine char * halten, das ist auch falsch.

Sie müssen eine Größe von n * sizeof(char) zuweisen, wobei n == Nummer char s. Nun sizeof(char) == 1 von C-Standard garantiert wird, kann Ihre Aussage zu

atm = malloc(requiredsize); 
res= malloc(requiredsize); 

Danach reduziert werden, sollten Sie für den Erfolg malloc() Anruf überprüfen UB zu verhindern, dass NULL-Zeiger zugreifen.

Aber dann werden Sie atm und res in jedem Aufruf fgets() und fscanf() werden überschrieben wird. Sie scheinen ein Array von Zeigern zu benötigen, nicht einen einfachen Zeiger, um die Aufgabe zu erledigen.

+0

Vielen Dank für das Hinweis. Ich multipliziere, was ich im Code vergessen habe zu erwähnen. Wie auch immer, das Problem besteht immer noch. – PythonNoob

1

Wenn atm und res sind Zeiger auf Arrays von char *, die wie die Absicht scheint, dann sollten sie als solche deklariert werden:

char **atm,**res; 

Sie dann Speicher für jede Zeichenfolge zuweisen müssen, als auch wie das Array als Ganzes:

while(fgets(buff,sizeof (buff),fp)!=NULL){ 
    atm[i] = malloc(200); // choose a suitable maximum size 
    res[i] = malloc(200); 
    fscanf(fp,"%s %s",atm[i],res[i]); 
    i++; 
} 

Dies entspricht viel mehr Ihrer Absicht - ich denke.

Es ist jedoch keine besonders gute Praxis. Mit fscanf mit %s gibt es keine Garantie, dass die Zeichenfolge, die Sie lesen, nicht länger ist als das, was Sie zugewiesen haben (ich denke, Sie können einen Breite Spezifizierer verwenden, um zu begrenzen, was es liest, zB %100s, aber das begrenzt wie viel gelesen wird) sowie wieviel ist gespeichert). Sie sollten auch die Rückgabe von malloc in jedem Fall überprüfen, um sicherzustellen, dass es erfolgreich war.

+0

Thannks das ist hilfreich. Also, was sollte anstelle von 'fscanf' verwendet werden? – PythonNoob

+1

@PythonNoob Sie würden denken, dass C möglicherweise eine bequeme Möglichkeit zum Lesen von Strings variabler Länge aus einer Datei enthalten, aber das ist nicht der Fall. Sie können "getline" verwenden, wenn es auf Ihrer Plattform verfügbar ist (und das Ergebnis dann in zwei separate Strings migrieren). TBH das verdient eine eigene Frage. – davmac

+0

Ich habe den von Ihnen vorgeschlagenen Code ausprobiert und es hat nicht funktioniert. Keine Kompilierungsfehler, aber ergibt einen "Segmentierungsfehler" bei der Ausführung. – PythonNoob