2015-11-22 1 views
0

J'écris moi-même un langage appelé SPL. Il a une commande d'entrée qui lit l'entrée de la propriété ISplRuntime.Input (il s'agit d'un TextReader). Toutes les autres commandes fonctionnent sur cette interface car je peux ainsi écrire différentes applications avec une seule bibliothèque! J'ai ensuite écrit une autre application de console pour tester ma langue. Ceci est ma mise en œuvre de ISplRuntime. Focus sur le Input et constructeur:Pourquoi StringReader lit-il ' uffff'?

public class MyRuntime : ISplRuntime { 
    protected TextReader reader; 
    protected bool stopped; 

    public object Current { 
     get; 
     set; 
    } 

    public virtual TextReader Input { 
     get { 
      return reader; 
     } 
    } 

    public object[] Memory { 
     get; 
     protected set; 
    } 

    public TextWriter Output { 
     get { 
      return Console.Out; 
     } 
    } 

    public bool Stopped { 
     get { 
      return stopped; 
     } 

     set { 
      stopped = value; 
      if (value) { 
       Console.WriteLine(); 
       Console.WriteLine ("Program has finished"); 
      } 
     } 
    } 

    public void ShowErrorMessage (string error) { 
     Console.WriteLine (error); 
    } 

    public MyRuntime() { 
     string s = Console.ReadLine(); 
     reader = new StringReader (s); 
     stopped = false; 
     Memory = new object[20]; 
    } 
} 

Lorsque le moteur d'exécution est construit, il demande d'entrée. Et utilisez cette entrée pour créer un StringReader et le renvoyer dans la propriété Input. Donc, chaque fois que l'entrée sera seulement une ligne.

Puis j'écris un programme en SPL qui produit l'entrée. Et c'est là que le problème est! Quand j'ai entré 1 1 1 1, il a imprimé 1 1 1 et a lancé FormatException. Voici comment je l'ai lu la saisie du numéro:

private bool ReadFromInput (ISplRuntime runtime, out int i) { 
    char stuffRead = (char)runtime.Input.Peek(); 
    if (stuffRead == ' ') { 
     i = 0; 
     runtime.Input.Read(); 
     return true; 
    } 

    if (char.IsNumber (stuffRead)) { 
     string numberString = ""; 
     while (char.IsNumber (stuffRead)) { 
      stuffRead = (char)runtime.Input.Read(); 
      numberString += stuffRead; 
     } 

     i = Convert.ToInt32 (numberString); //This is where the exception occured! (Obviously, because there is no other methods that would throw it) 
     return true; 
    } else { 
     i = 0; 
     return false; 
    } 
} 

Le paramètre runtime est juste le temps d'exécution que vous venez de voir. Il renvoie true s'il lit avec succès un nombre. Et ce nombre est le paramètre de sortie i. Après avoir utilisé la fenêtre "Regarder" dans Visual Studio, j'ai découvert que la chaîne de nombre est "1\uffff" lorsque l'exception est levée. Voilà pourquoi il le jette! Je sais (pense) que '\uffff' est le caractère de fin de ligne. Mais pourquoi cela apparaîtrait-il dans ma contribution? Je sais (pense) que presser Ctrl + Z fait une fin de ligne, mais je ne l'ai pas fait! Puis j'ai vérifié dans la fenêtre de la montre. Ceci est le résultat:

enter image description here

Je vois qu'il ya un champ appelé _s et je pense que la chaîne est que je l'ai dit à lire. Voir? _s ne contient même pas '\uffff', comment se fait-il qu'il le lit?

post-scriptum Je connais déjà la solution. J'ai juste besoin de changer la boucle while un peu et cela fonctionne. Mais je veux savoir pourquoi lit-il une fin de ligne.

+0

_pos = 7, _length = 7. Vous n'avez pas à appuyer sur Ctrl + Z pour obtenir la condition de fin de fichier sur un StringReader, il ne dispose plus de caractères. –

+0

@HansPassant Donc le dernier caractère lu est toujours ''\ uffff' '? – Sweeper

+0

Si vous lisez un personnage et qu'il n'y en a plus, il n'y a pas de dernier caractère. Et vous aurez -1. –

Répondre

2

Il n'y a pas de mystère ici - \uffff est produite par votre code. Tout ce dont vous avez besoin est de lire la documentation et de comprendre les méthodes que vous appelez.

TextReader.Peek Method

Valeur de retour
Type: System.Int32
Un entier représentant le caractère suivant à lire, ou -1 il n'y a plus de caractères sont disponibles ou le lecteur ne pas recherche de soutien.

TextReader.Read Method

Valeur de retour
Type: System.Int32
Le caractère suivant du lecteur de texte ou -1 s'il n'y a plus de caractères disponibles.

espère que vous voyez la relation entre -1 (0xffffffff) et \uffff.