2010-02-21 9 views
1

Je fais une mission hw et mon professeur utilise ce code pour tester notre programme:caractère EOF dans XCode (ctrl + d)

int main() 
{ 
    const int SZ1 = 10; 
    const int SZ2 = 7; 
    const int SZ3 = 5; 
    float array1[SZ1]; 
    float array2[SZ2]; 
    float array3[SZ3]; 

    DisplayValues(SortValues(GetValues(array1, SZ1), SZ1), SZ1); 
    DisplayValues(SortValues(GetValues(array2, SZ2), SZ2), SZ2); 
    DisplayValues(SortValues(GetValues(array3, SZ3), SZ3), SZ3); 

    return EXIT_SUCCESS; 
} 

float *DisplayValues(float *p, size_t n) 
{ 
    float previous = *p, *ptr, *end = p + n; 

    setiosflags(ios_base::fixed); 
    for (ptr = p; ptr < end; ++ptr) // get each element 
    { 
     cout << *ptr << '\n'; 
     if (ptr != p)     // if not first element... 
     { 
     if (previous < *ptr)  // ...check sort order 
     { 
      cerr << "Error - Array sorted incorrectly\n"; 
      return NULL; 
     } 
     } 
     previous = *ptr;    // save this element 
    } 
    resetiosflags(ios_base::fixed); 

    return p; 
} 
#endif 

J'utilise

float *GetValues(float *p, size_t n) 
{ 
    float input; 
    float *start = p; 

    cout << "Enter " << n << " float values separated by whitespace: \n"; 

    while (scanf("%f", &input) == 1) { 
     *p++ = input; 
    } 
    return start; 
} 

pour obtenir des commentaires de la fenêtre du terminal comme il l'a demandé, et utilisez ctrl + d pour entrer un caractère EOF afin que le premier appel à DisplayValues ​​(SortValues ​​(GetValues ​​(array1, SZ1), SZ1), SZ1) se produise. Cependant, le reste du programme se termine juste sans me laisser entrer de nouvelles valeurs quand DisplayValues ​​(SortValues ​​(GetValues ​​(array2, SZ2), SZ2), SZ2); est appelé. Y a-t-il une raison ou une solution pour cela? Merci.

+0

Notez que votre GetValues ​​n'utilise pas du tout * n * lors de la lecture des valeurs (dans votre boucle avec scanf). –

Répondre

0

Le problème est lié à l'utilisation d'EOF comme délimiteur. scanf lira dans l'EOF, avant qu'il puisse acquérir le prochain flotteur qu'il veut. scanf retournera EOF pour vous dire ce qu'il a trouvé, mais l'EOF ne quittera pas le tampon, donc la prochaine fois que vous appelez scanf, il lira toujours EOF et reviendra immédiatement. Voir: scanf

Dans votre fonction GetValues, puisque vous avez la taille du tableau, vous devriez simplement lire les nombres jusqu'à ce que vous ayez autant de flottants, au lieu d'attendre un EOF. De cette façon, vous évitez un débordement ainsi que l'utilisation incorrecte d'EOF.

4

Le CTRLcaractère D (hex 04) n'est pas un caractère de fin de fichier en tant que tel. Si vous appuyez sur cette séquence de touches, le pilote du terminal signale qu'il s'agit de la fin du flux d'entrée et toute autre lecture de ce flux sera traitée comme si le "fichier" était terminé. En fait, vous pouvez changer le caractère utilisé pour cela avec la commande stty sous UNIX.

Ce qui se passe lorsque vous appuyez sur cette séquence est qu'aucune autre entrée ne sera donnée au programme. Vous devez trouver une séquence plus intelligente pour délimiter vos données (comme, par exemple, newline (0x10)).

Mais cela vous obligera à des chaînes d'entrée plutôt que des flotteurs (vous pouvez utiliser fgets pour obtenir une chaîne et sscanf pour extraire un flotteur après que vous avez vérifié pour une ligne vide). Une autre possibilité est d'utiliser -1 comme valeur sentinelle spéciale (en supposant que -1 n'est pas une entrée valide) mais attention aux comparaisons à virgule flottante, elles ne sont parfois pas ce que vous attendez.

Ma suggestion est d'aller la route fgets/sscanf mais, puisque vous devez obtenir n flotteurs, votre GetValues devrait aller quelque chose comme ceci:

float *GetValues (float *p, size_t n) { 
    float input; 
    float *start = p; 
    cout << "Enter " << n << " float values separated by whitespace: \n"; 
    while (scanf("%f", &input) == 1) { 
     *p++ = input; 
     if (--n >= 0) 
      break; 
    } 
    return start; 
} 

qui arrêtera d'obtenir des valeurs une fois que vous avez atteint votre limite. Gardez à l'esprit que ce n'est pas parfait. J'ai laissé au moins un problème en raison du fait qu'il s'agit de devoirs (vous pouvez ne jamais le frapper, en fonction de vos données d'entrée).

Je devrais également mentionner qu'il est quelque peu inhabituel de mélanger les sémantiques d'E/S C++ et C (cout et scanf) - vous devriez vraiment choisir l'un ou l'autre. S'il s'agit d'une affectation C++, vous trouverez que C++ a une façon plus riche de faire des E/S. Si c'est C, alors cout n'a pas sa place dans le code et vous devriez probablement utiliser printf. Je ne dis pas que ce ne sera pas travail, juste que c'est un mélange inhabituel.