Hello All

I am writing a program, for homework, that would rank 3 runners in 1st, 2nd and 3rd places based on their finish times. I need to bubble sort the names, but it fails. Here is what I have:

//Constants Used:
 const int iLength = 21;                 //20 Chars + 1 null terminator.

//Variable Declaration Section:
//3 char. variables to hold 3 user input.
char cRunner1[iLength], cRunner2[iLength], cRunner3[iLength];
char cExtraName[iLength];               //1 extra name to help in the sorting.

Later I have:

cout << "Name of Runner number 1: ";
cin.getline(cRunner1, iLength);

and then in an If Statement that swaps the values of the finishing times I have:

cExtraName = cRunner1;
cRunner1 = cRunner2;
Runner2 = cExtraName;

I am having 2 problems:

1st problem, if I enter a name < 20 characters the system hangs, and does not go any further from the cin.getline line.

2nd problem, there seems to be a data type issue when I am swapping the names to sort them.

Thanks in advance to any help.

Waseem

swapping character arrays can not be done with the = operator. Instead you have to call strcpy() to copy them.

strcpy(cExtraName,cRunner1);
strcpy(cRunner1, cRunner2)
strcpy(cRunner2, cExtraName);

As for your first problem you will have to post all the code so that we can find the problem. If you don't want to do that then search for the problem somewhere before that getline().

Also, when you swap the name you also have to swap the runtime so that the names and runtimes say in the same order.

Thank You Ancient Dragon

OK I changed the statements to use the strcpy function, and for the code paste as you suggested here it is.

Any line that is remarked at the edge and not in line with the code is a line that is producing a problem. The problems are listed below in order from top to bottom.

//RQ_SC_05.cpp
// RunnerQualifier_SC.cpp
// Runner's ranking according to race finish times.
// Purpose: To rank 3 runners based on finish time.
// Compiled using aCC -AA
// CS 110A SECTION 601.
// Lab homework 03.
// March 18th 2008.


#include <iostream>
#include <fstream>      //Required for File I/O Operations.
#include <iomanip>      //Required for I/O Formatting.
#include <stdlib.h>     //Required for System functions.
//#include <process>    //Required for System functions.
using namespace std;

int main(int argc, char *argv[])
{
        //File Output direction:
        ofstream outputFile;
        outputFile.open("RaceRankings.txt");

        //Constants Used:
        const int iLength = 21;   //20 Chars + 1 null terminator.

        //Variable Declaration Section:
        int iCounter;                           //Simple Integer counter.
        //3 char. variables to hold 3 user input.
        char cRunner1[iLength], cRunner2[iLength], cRunner3[iLength];
        double dFinish1, dFinish2, dFinish3;  //3 variables to hold 3 user inputs.
        char cExtraName[iLength];             //1 extra name to help in the sorting.
        double dExtraNum;                       //1 extra variable to help in the sorting.

        //Display message for user:
        cout << "Please provide Cyborg Computer with the names and "
             << "finishing times for the top 3 runners\n";
        cout << "Reminder: Names can not be longer than 20 characters"
             << " and running times must be greater than zero.\n\n";

        //Input Section:
        //Accept the name of the runner 1.
        cout << "Name of Runner number 1: ";
        cin.getline(cRunner1, iLength);

        //Ignore anything left in the keyboard buffer.
        cin.ignore();

        cout << "Reminder: finishing times must be greater than zero.\n";
        cout << "Finish Time for Runner number 1: ";
        cin >> fixed >> showpoint >> setprecision(2) >> dFinish1;
        cout << "\n\n";
//Ignore anything left in the keyboard buffer.
        cin.ignore();
        
        //Accept the name of the runner 3.
        cout << "Name of Runner number 3: ";
        cin.getline(cRunner3, iLength);

        cout << "Reminder: finishing times must be greater than zero.\n";
        cout << "Finish Time for Runner number 3: ";
        cin >> fixed >> showpoint >> setprecision(2) >> dFinish3;
        cout << "\n\n";
        
        //Ignore anything left in the keyboard buffer.
        cin.ignore();  

        //Calculation Section:
        //Compare the times of Runner 1 and Runner 2, and bubble sort if needed.
        if (dFinish1 > dFinish2)
        {
                dExtraNum = dFinish1;
                dFinish1 = dFinish2;   
                dFinish2 = dExtraNum;
        
                strcpy(cExtraName , cRunner1);
                strcpy(cRunner1 , cRunner2);
                strcpy(cRunner2 , cExtraName);
        }
        
        //Compare the times for Runner 2 and Runner 3, and bubble sort if needed.
        if (dFinish2 > dFinish3)
        {
                dExtraNum = dFinish2;
                dFinish2 = dFinish3;   
                dFinish2 = dExtraNum;
        
                strcpy(cExtraName , cRunner2);
                strcpy(cRunner2 , cRunner3);
                strcpy(cRunner2 , cExtraName);
        }
        
        //Compare the times for Runner 1 and Runner 2, and bubble sort if needed.
if (dFinish1 > dFinish2)
        {
                dExtraNum = dFinish1;
                dFinish1 = dFinish2;
                dFinish2 = dExtraNum;
                
                strcpy(cExtraName , cRunner1);
                strcpy(cRunner1 , cRunner2);
                strcpy(cRunner2 , cExtraName);
        }
                
        //Output Section:
        cout << "In First  place came    " << cRunner1 << " with a finish time of " << dFinish1 << " seconds.\n";
        cout << "In Second place came    " << cRunner2 << " with a finish time of " << dFinish2 << " seconds.\n";
        cout << "and in Third place came " << cRunner3 << " with a finish time of " << dFinish3 << " seconds.\n";
        
        //Add code to save to the text file.

        //Return Results:
        return 0;
}

Line 17 produces this error:
Error 112: "RQ_SC_05.cpp", line 17 # Include file <process> not found.
#include <process> //Required for System functions.

Do you think I need to talk to the system administrator about that? I wanted to use the function

//Clear the screen from anything on it to clear the interface.
        system("cls");

to clear the screen so that I will have a nice interface.

So the major problem is that line 46 runs and produces the output on the screen waits for the user to enter something, and if it is less than 20 characters it hangs and line 51 never comes on the screen.

Thanks and I hope you will find some styles issues and point them out. I am a VB programmer and now learning C++ so that is where they come from.

Thanks for your time and efforts I do appreciate it.

Thank You Ancient Dragon

After I posted my reply I went back again and worked some more on my homework and I got some good results.

I still get this error:

Error 112: "RQ_SC_01.cpp", line 15 # Include file <process.h> not found.
#include <process.h> //Required for System functions.

When I add the h or without the h.

Also, now I have a working model, but it still goes through an infinite loop when the name approaches the max which is set for 25 now just for me to be able to plug in the supplied data.

The code, now looks like

//Input Section:
        //Accept the name of the runner 1.
        cout << "Name of Runner number 1: ";
        cin.getline(cRunner1, iLength);

        while (dFinish1 <= 0)
        {
                cout << endl << "Reminder: finishing times must be greater than zero\n";
                cout << "Finish Time for Runner number 1: ";
                cin >> fixed >> showpoint >> setprecision(2) >> dFinish1;
                cout << "\n\n";
        }
        
        //Ignore anything left in the keyboard buffer.
        cin.clear();

Remember const int iLength = 26; //25 Chars + 1 null terminator. and I also have

//Initalize the variables
        dFinish1 = 0.0; //The value that would enter the loop.

.

When I run this code with long names it gives me an infinite loop:

Reminder: finishing times must be greater than zero
Finish Time for Runner number 1:


Reminder: finishing times must be greater than zero
Finish Time for Runner number 1:


Reminder: finishing times must be greater than zero
Finish Time for Runner number 1:


Reminder: finishing times must be greater than zero
Finish Time for Runner number 1:


Reminder: finishing times must be greater than zero
Finish Time for Runner number 1:

I do not know what is going on with the name stuff. If it is set for 25 characters long, why is it not being accepted or at least flushed by the cin.clear() line?

One thought if you do not mind. Could I use the clear UNIX command to clear the screen or is it spelled clr?

Thanks a Million.

So you are using *nix? In that case you don't need process.h. The system() function is declared in stdlib.h. Read this man page.

<<When I run this code with long names it gives me an infinite loop:
Because that while loop has no way to stop. How does bFinish1 every get set to some value > 0 so that the loop will terminate ?

When you enter a name longer than the input allows, the cin.getline( ) sets an error condition, so no further input will be processed. If you expect to handle overly long input, you need to follow it with a

cin.clear( ); //resets error flags
cin.ignore( nn, '\n' ); //set nn to some number reasonably big,

Hi Ancient Dragon

Because that while loop has no way to stop. How does bFinish1 every get set to some value > 0 so that the loop will terminate ?

I though that by setting the value to render the While condition to be true, it will enter the loop, and within the loop I will ask the user for input thus stopping the process until the user enters something that will change the value of the while condition to false and exits the loop.

My reasoning is to check if the user enters a negative number for a time stamp. The runner has to consume some time to finish the race thus time has to be a positive quantity.

I set the condition to be while (dFinish1 <= 0) and set dFinish1 to zero. The loop will enter, the system will ask the user to input the value of dFinish1. If the user enters a negative number, or zero the input is tossed out and the system will ask again. This will go on until the value entered for dFinish1 is positive.

while (dFinish1 <= 0)
{
      cout << endl << "Reminder: finishing times must be greater than zero\n";
      cout << "Finish Time for Runner number 1: ";
      cin >> fixed >> showpoint >> setprecision(2) >> dFinish1;
      cout << "\n\n";
}

Do I have a logical error here?

Hello vmanes

When you enter a name longer than the input allows, the cin.getline( ) sets an error condition, so no further input will be processed. If you expect to handle overly long input, you need to follow it with a

cin.clear( ); //resets error flags
cin.ignore( nn, '\n' ); //set nn to some number reasonably big,

Thanks for your reply. I was under the impression that cin.getline(cRunner1, iLength);
will read into cRunner1 iLength -1 characters and stop accepting anything beyond that. Or is it that you are telling me that what actually happens is that the input past iLenght is used for the subsequent input statements? That is if I enter a name that happens to be iLenght + 5 long the next 5 cin >> statements will be affected?

Yes I do have cin.ignore() at the next line after the } of the while loop. Do I also need a cin.clear()? Is cin.clear() an alternative to cin.ignore() that will flush the whole keyboard buffer?

If you enter 25 characters to a string variable that holds 20, the remaining 5 will be left on the input stream, and may be read by the next input operation - which is something you usually don't want.

cin.clear() does not remove anything from the stream, it simply resets the error condition(s) back to a good state. You still need to use the cin.ignore( ) to remove the remaining (unwanted) characters from the stream. The clear must be done first.

Thank You vmanes,

Just as I suspected. I would love it if you would take a look at the code that I posted in a reply to Ancient Dragon and tell me if all looks correct. Am I using the right formats, am I too wordy in my comments stuff that would enhance my style and not the code per se.

Thanks

Here's your code, with comments trimmed down. You should never make a comment that states the obvious. With good variable names and clear logic, the statements themselves should do most of your documentation. You should identify what a chunk of code is doing, sort of like outlining. Keep comments short, no need for full sentences.

The only changes I made to the code itself were to update you to <cstdlib>, move the constant for string length to global scope (if you add functions, this is handy), and put the third comparison of the times inside the second one's block. That recomparing the runner 1 and 2 values is only needed if 2 & 3 swapped.

Watch for lines that run over 80 characters long - these don't always print out well or display completely in the editor without horizontal scrolling. (the forum displays less than 80 characters when numbering in present, so there's a bit of wrapping in what you see below that won't be there in your editor.)

(you need to add the input for Runner 2 !)

//RQ_SC_05.cpp
// RunnerQualifier_SC.cpp
// Runner's ranking according to race finish times.
// Purpose: To rank 3 runners based on finish time.
// Compiled using aCC -AA
// CS 110A SECTION 601.
// Lab homework 03.
// March 18th 2008.


#include <iostream>     //basic I/O
#include <fstream>      //File I/O 
#include <iomanip>      //I/O Formatting
#include <cstdlib>        //System functions.
//#include <process>    //OS unique System functions.
using namespace std;
   
//Program Constants 
const int iLength = 21;   //string length

int main(int argc, char *argv[])
{
   ofstream outputFile;
   outputFile.open("RaceRankings.txt");


   int iCounter;                           
   
   char cRunner1[iLength], cRunner2[iLength], cRunner3[iLength];//Runners' names
   double dFinish1, dFinish2, dFinish3;  //Runners' times
   char cExtraName[iLength];             //for swapping names.
   double dExtraNum;                     //for swapping times

   //Display prompt
   cout << "Please provide Cyborg Computer with the names and "
          << "finishing times for the top 3 runners\n";
   cout << "Reminder: Names can not be longer than 20 characters"
          << " and running times must be greater than zero.\n\n";

   //Input Section:
   cout << "Name of Runner number 1: ";
   cin.getline(cRunner1, iLength);
   cin.ignore();

   cout << "Reminder: finishing times must be greater than zero.\n";
   cout << "Finish Time for Runner number 1: ";
   cin >> fixed >> showpoint >> setprecision(2) >> dFinish1;
   cout << "\n\n";
   cin.ignore();

   cout << "Name of Runner number 3: ";
   cin.getline(cRunner3, iLength);

   cout << "Reminder: finishing times must be greater than zero.\n";
   cout << "Finish Time for Runner number 3: ";
   cin >> fixed >> showpoint >> setprecision(2) >> dFinish3;
   cout << "\n\n";

   cin.ignore();  

   //Calculation Section:
   //Compare the times of Runners, sort into ascending order
   if (dFinish1 > dFinish2)
   {
      dExtraNum = dFinish1;
      dFinish1 = dFinish2;   
      dFinish2 = dExtraNum;

      strcpy(cExtraName , cRunner1);
      strcpy(cRunner1 , cRunner2);
      strcpy(cRunner2 , cExtraName);
   }

   if (dFinish2 > dFinish3)
   {
      dExtraNum = dFinish2;
      dFinish2 = dFinish3;   
      dFinish2 = dExtraNum;

      strcpy(cExtraName , cRunner2);
      strcpy(cRunner2 , cRunner3);
      strcpy(cRunner2 , cExtraName);

      if (dFinish1 > dFinish2)//only recompare 1 & 2 if 2 & 3 swapped
      {
         dExtraNum = dFinish1;
         dFinish1 = dFinish2;
         dFinish2 = dExtraNum;

         strcpy(cExtraName , cRunner1);
         strcpy(cRunner1 , cRunner2);
         strcpy(cRunner2 , cExtraName);
      }
   }


   //Output Section:
   cout << "In First  place came    " << cRunner1 << " with a finish time of " 
        << dFinish1 << " seconds.\n";
   cout << "In Second place came    " << cRunner2 << " with a finish time of " 
        << dFinish2 << " seconds.\n";
   cout << "and in Third place came " << cRunner3 << " with a finish time of " 
        << dFinish3 << " seconds.\n";

   //Add code to save to the text file.

   return 0;
}
This article has been dead for over six months. Start a new discussion instead.