2009-11-15 10 views
6

Ich habe ein Problem, ich konstruiere eine Zeichenfolge in einer Schleife und die Ausgabe dieser Zeichenfolge zu Stout zeigt die Zeichenfolge und ein Zeichen "y" mit zwei Punkten darüber als das letzte Zeichen.Wofür steht 'y' in der Ausgabe in C?

Was ist das?

Ich schaffe die Zeichenfolge in dieser Funktion:

char get_string(char *buf, int ble, FILE *fp, char del) 
{ 
    int i = 0; 
    int c; 
    char result; 

    memset(buf, 0, BUFLEN); 

    do { 

     c = fgetc(fp); 

     if (c == del) { 
      buf[i] = '\0'; 
      result = c; 
      break; 
     } else if(c == '\n') { 
      buf[i] = '\0'; 
      result = '\n'; 
      break; 
     } else { 
      buf[i] = c; 
      i++; 
     } 

    } while (c != EOF); 

    return result; 
} 

und dann die buf verwenden und das Ergebnis als in einer anderen Funktion folgt:

char pair[BUFLEN]; 
char end; 

do { 

     end = get_string(pair, BUFLEN, fp, ';'); 
     printf("Result: %s\n",pair); 

} while (pair != NULL); 

Die letzte Iteration der oben Druckt „Ergebnis: y "Ich habe keine Ahnung warum.

+0

Können Sie Ihren Code posten? – cschol

+0

Ich habe meinen Code hinzugefügt – goe

Antwort

8

ÿ ist das Zeichen für das Zeichen, das (in Unicode und vielen ISO-8859-? -Kodierungen) den Ordinalwert 0xFF hat. Dieser Wert, auch als Dezimalzahl 255 bekannt, wird in einigen Kontexten auch als "Dateiendezeichen" (EOF) verwendet - obwohl es keinen Standard gibt, der das Zeichen als solchen definiert (AFAIK), den Wert -1 wird in vielen Sprachen (z. B. C) zurückgegeben, wenn Sie versuchen, mehr aus einer Datei zu lesen, die erschöpft ist ("am Ende der Datei").In der Praxis bedeutet daher ein unerwartetes ÿ in Ihrer Ausgabe oft, dass Sie fälschlicherweise ein Byte interpretieren, das "Ende von etwas" bedeuten soll (ein Byte, das mit allen auf eins gesetzten Bits codiert ist), als wäre es Teil von der anzuzeigende Text

+0

Danke, das hat funktioniert – goe

+0

Kleine Nitpick - es ist die Glyphe für den Unicode-Codepunkt 'U + 00FF', die in UTF-8 dem Byte' 0xFF' entspricht. –

+0

@Jesse, in Unicode kann es geschrieben werden U + 00FF (das hat den Ordinalwert 255 in Dezimal, FF in Hex, etc), in ISO-8859-1 (& c) natürlich kann es nicht mit einem geschrieben werden U 'Präfix (während 0xFF immer noch richtig ist ;-), und dieser Codepunkt in UTF-8 ist als eine Zwei-Byte-Sequenz codiert, 0xC3 0xBF, die nichts mit dem OP-Problem zu tun hat. –

1

Wenn Sie "Ihre Zeichenfolge in einer Schleife erstellen", erinnern Sie sich daran, es ordnungsgemäß mit einem '\0' zu beenden? Wenn die Schleife einem Zeichen-Array Zeichen zuweist, sollte das letzte Array-Element '\0' lauten.

Ok, nachdem Sie den Code gesehen haben, beenden Sie die Zeichenfolge.

EDIT:

Sieht aus wie Sie die EOF-Zeichen in der Zeichenfolge sind inklusive. Dies ist ein Fall, in dem die Zeichenfolge nicht ordnungsgemäß beendet wird. Sie sollten in Ihrer If-else-Struktur nach einem EOF suchen und es richtig handhaben.

Eine andere Sache, die ich bemerkt:

Sie eine int c zu einem char result zuweisen, wenn sie von Ihrer Funktion zurückkehrt. Der Compiler hätte Sie warnen sollen, dass Sie versuchen, einen größeren Datentyp in einen kleineren Datentyp zu überführen. Je nachdem, welchen Zweck der Rückgabewert hat, würde ich daran denken, den Rückgabedatentyp auf int zu ändern.

+0

Ja, ich denke, schau oben. – goe

2

'y' mit zwei Punkten darüber ist Zeichen 0xFF (in Latin-1 - die Standard-Codepage für die Konsole).

0xFF als 8-Bit-Wert mit Vorzeichen ist -1.

Suchen Sie nach Stellen, an denen Sie -1 als Zeichen ausgeben (oder -1 als Zeichen verwenden und dann drucken).

9

Sie verwenden eine do - while Schleife, was bedeutet, dass Sie den Schleifenkörper für EOF vor der Prüfung sind die Ausführung, so dass Sie am Ende als auch EOF in Ihrem Puffer setzen. Der Wert EOF von -1 wird in den Zeichenbereich übersetzt, in dem er ÿ entspricht. Ich würde Ihnen empfehlen, nur zu einer üblicheren while Schleife zu wechseln, weil es diese Bedingung natürlicher behandelt.

1

Ihre if -Anweisung, die endet mit einem sonst den Charakter in den Puffer setzen hat zwei Fehler:

  1. Es herauszufiltern nicht die EOF speziellen „Zeichen“, die das Ende des Stroms bedeutet
  2. Es wird nicht auf Pufferüberlauf geprüft, indem der Wert i mit dem Wert BUFLEN verglichen wird.

Das erste Problem ist die Ursache für Ihre ÿ Charakter, wenn der Strom endet, können Sie die EOF Zeichen in den Puffer hinzufügen, dann wird die Schleife beendet.

Das Update ist eine Klausel in Ihre if-else Erklärung zu setzen, dass filtern weg, wie folgt aus:

} else if (c != EOF) { 
    buf[i] = c; 
    i++; 
} 

Das zweite Problem, das Sie entscheiden müssen, wie vor der Befestigung zu handhaben, aber es soll fixiert werden .

0

Sie terminieren Ihre Zeichenfolge nicht ordnungsgemäß. Wenn das Lesen von fp niemals "del" oder "\ n" zurückgibt und Sie EOF erreichen, wird es keinen Null-Terminator geben. Sie müssen Ihren Code reparieren.