tags:

views:

154

answers:

6

Hi there

I'm in the midst of a university project and have decided to implement a method that can accept information from a text file (in this instance called "locations.txt"). input from the text file will look like this:

London
345
456
Madrid
234
345
Beinjing
345
456
Frankfurt
456
567

The function looks like this currently (and you will notice I am missing the While condition to finish adding input when reaches end of text in locations.txt, i tried using eof but this didnt work?!). Also get function expects a char and so cant accept input thats a double which is what the latitude and longitude are defined as...

void populateList(){
  ifstream inputFile;
  inputFile.open ("locations.txt");
  temp  = new locationNode; // declare the space for a pointer item and assign a temporary pointer to it


  while(HASNT REACHED END OF TEXT FILE!!)
  {
     inputFile.getline(temp->nodeCityName, MAX_LENGTH);
     // inputFile.get(temp->nodeLati, MAX_LENGTH);
     // inputFile.get(temp->nodeLongi, MAX_LENGTH);

     temp->Next = NULL; //set to NULL as when one is added it is currently the last in the list and so can not point to the next

     if(start_ptr == NULL){ // if list is currently empty, start_ptr will point to this node

        start_ptr = temp;
     }

     else {
        temp2 = start_ptr;
        // We know this is not NULL - list not empty!
        while (temp2->Next != NULL)
           {  
            temp2 = temp2->Next; // Move to next link in chain until reach end of list
           }

        temp2->Next = temp;
     }
  }
  inputFile.close();
}

Any help you can provide would be most useful. If I need to provide anymore detail I will do, I'm in a bustling canteen atm and concentrating is hard!!

A: 

in the input file, each token is seperated by a carriage return and is on a new line which is not clear above

Greenhouse Gases
This is not an answer, it's a comment. Please delete.
unwind
@unwind, I don't think the OP doesn't have enough rep to comment.
Kristo
Do not add information using answers - edit your question.
anon
@Kristo - you can always comment on your own questions.
Steve Fallows
+2  A: 

You can put the getline() call as the condition for the while loop. Its return value will evaluate to false once you reach EOF.

Kristo
+1  A: 

You could use fstream and then do:

double d;
fs>>d;
codymanix
+4  A: 
std::string city;
double lat, lgt;

while( (inputFile >> city ) &&  (inputFile >> lat) && (inputFile >> lgt ) )   {
    // do something with values
}
anon
Andreas Brinck
Andreas Brinck
@Andreas There's a conversion from stream to bool. This is the canonical way of testing if stream operations succeeded.
anon
@Andreas You might want to take a look at my blog article on the subject - http://punchlet.wordpress.com/2009/12/01/hello-world/
anon
@Neil Do you mean `ios::operator void*` (which is essentially the same thing)?
Andreas Brinck
@Andreas Oops, sorry, that is what I meant.
anon
Why do you make it three separate reads? Assuming the the file is well-formed, you should be able to always do one complete operation, or am I missing something here?
Space_C0wb0y
@Space_C0wb0y, that's just it. You can't assume anything the user does is well-formed.
Kristo
@Space_C0wb0y The form in >> a >> b >> c will also work but does all the reads even if the first one fails, which may or may not matter.
anon
Well, but then, what do you do if you discover the error? If you cannot recover, you might as well fail.@Neil: Ok, so no basic reason I do not know, thanks.
Space_C0wb0y
Another problem with this: it won't work with cities like "New York" or "Sao Paulo" or "Ho Chi Minh City", since reading into a string gets only "New" or "Sao" or "Ho", leaving the rest to be read as doubles.
David Thornley
@Neil Butterworth: Why not just: while (std::getline(inputFile,city) >> lat >> lgt ) {} If the first one fails it sets bad bit and the remaining operations then do nothing.
Martin York
Hi all, thank you for your contributions. I've tried various input formats for the text file. the idea is the first token will be city name, second token will be a double value stored in a double variable, and again the third is a double value stored in a double variable. at the moment i was concentrating on getting the city name using getline such that:inputFile.getline(temp->nodeCityName, 35, ',');
Greenhouse Gases
but the delimiter seems to not be working and it takes in the 35 bytes regardless... including the delimiter character! in java, similar functions take tokens at a time but i understand this is not the case unless explicitly stated to the compiler, so i couldnt have:inputfile >> cityName >> lati >> longi; // insufficient?
Greenhouse Gases
Wow, im such a stack overflow noob just realised theres loadsa answers below this! just to say, using get as opposed to getline solves the issue i mentioned. this is yet another example of fatigue making me make silly mistakes!
Greenhouse Gases
A: 

I would suggest you to use the implementation written by Neil Butterworth. When I'm doing that kind of programs I usually do it like that. You can compress the sentence by writing:

while (cin >> city >> lat >> lgt)
{
    // do stuff
}

But in that case i don't know what would happen if one of the params isn't read correctly, so try Neil's suggestion.

Baha
+2  A: 

The getline() is important, since something like cin >> str; will read only the first word of city names like "New York" or "Ho Chi Minh City". Put it in the while loop condition, as Kristo suggests.

After that, you have two possibilities. You can use standard streams to read in a double, in which case you should make sure you're reading all appropriate newlines. (file >> double_var; leaves the following newline to read, so a following getline() will get the rest of the line, which is empty, rather than the next one.) This sort of thing works when you're sure the input is well-formed, which is a lot more common in homework problems than the real world.

Alternately, you can use getline() to read in each line, and then convert the text to double yourself. There are, of course, different ways. The C function atod() is the easiest, but will return 0 either if the number is 0 or it isn't a number. The C function strtod() is more complicated to set up, but will distinguish between those two cases. You can use the C++ solution istringstream, but in this case it looks like far more trouble than it's worth.

David Thornley