1

I've got a simple program which is supposed to take in an input file which contains a first and last name and then various integers afterwards. I'd like to be able to write the first two strings for the names into their own variables, and the rest of the integers into their own array. I have code setup already, with the strings read into their own variables, however when I attempt to write the integers into their own array, I get an infinite loop of the first two strings alternating forever. Here is the code.

int main() 
{
    std::string first_name,last_name;

    int scores_tem[20];
    int i=0;

    std::ifstream filen ("input.txt");
    if (filen.is_open())
    {
        while(!filen.eof())
        {
            filen >> first_name >> last_name;
            for(i;i<20;i++)
            {
                filen>>scores_tem[i];
            }
        }
    }
}
robbannn
  • 4,643
  • 1
  • 27
  • 41
zzzzzzzch
  • 29
  • 8
  • 1
    Start by getting rid of this: [**`while(!filen.eof())`**](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) is *wrong*. And I think [`std::istringstream`](http://en.cppreference.com/w/cpp/io/basic_istringstream) in conjunction with [`std::getline`](http://en.cppreference.com/w/cpp/string/basic_string/getline) are likely what you're looking for for per-line processing if you have multiple lines of "firstname lastname numbers.." laid out. – WhozCraig Sep 11 '14 at 07:57
  • Oh, and you never reset `i` after your first iteration. Change `for(i;` to `for(i=0;` – WhozCraig Sep 11 '14 at 08:09
  • If you have more than one full name, and there are less than 20 integers after one of them, the stream will enter an error state on the next name and not read anything after that point (which means it never reaches the end). – molbdnilo Sep 11 '14 at 08:22
  • According to the instructions, it is highly recommended that I am to use only the ">>" operator and not getline. – zzzzzzzch Sep 11 '14 at 08:42
  • And removing the while(!filen.eof()) only allows me to read the first line, how can I begin reading from the next line in the input file without using getline? – zzzzzzzch Sep 11 '14 at 08:46
  • IMHO you cannot both say *the input is organized by lines* and *I should not use getline*. `getline` (C and C++ versions) exists explicitely to process line oriented input, where direct `>>` allow to get input independently of EOL. – Serge Ballesta Sep 11 '14 at 09:12

2 Answers2

0

This solution is made after the criteria that you are not allowed to use getline, and that the number of integers after the two names are always 20. This solution is not very generic, and i dont like it, but it does the job.

#include <string>
#include <iostream>
#include <fstream>

int main()
{
    std::string first_name, last_name;

    int scores_tem[20];
    int i = 0;

    std::ifstream filen("input.txt");
    if (filen.is_open())
    {
        while (!filen.eof())
        {
            filen >> first_name >> last_name;
            for (i = 0; i < 20; i++)
            {
                filen >> scores_tem[i];
            }
            std::cout << first_name << " " << last_name;
                for (auto &k : scores_tem)
                    std::cout << " " << k;
                std::cout << std::endl;
        }
        std::cin.get();
    }
}

Found another solution that also takes care of the event of errenous input.

#include <string>
#include <iostream>
#include <fstream>

int main()
{
    std::string first_name, last_name;

    int scores_tem[20];
    int i = 0;

    std::ifstream filen("input.txt");
    if (filen.is_open())
    {
        while (true)
        {
            if (!(filen >> first_name)) break;
            if (!(filen >> last_name)) break;
            for (i = 0; i < 20; i++)
            {
                if(!(filen >> scores_tem[i])) break;
            }
            if(!(filen.get())) break;

            std::cout << first_name << " " << last_name;
            for (auto &k : scores_tem)
                std::cout << " " << k;
            std::cout << std::endl;
        }
        std::cin.get();
    }
}
robbannn
  • 4,643
  • 1
  • 27
  • 41
  • What does the auto &k: do? And is the cin.get() required for this to work? – zzzzzzzch Sep 11 '14 at 09:10
  • `auto &k:` extracts one of whatever type scores_tem holds, an integer in this case, into the variable k. The `&` makes it a reference, which means no copy is made of the extracted element. `std::cin.get();` is nothing necessary for the code to work. Its something i use to avoid the cmd from closing before i can see what it says. With it i haveto push `return` before it closes. – robbannn Sep 11 '14 at 09:14
  • Right, it works now, but now it either infinitely loops through only the first line of the file or if I remove the !eof it will run through only the first line, once. Is there any way to simply direct the program to switch to a new line? – zzzzzzzch Sep 11 '14 at 14:11
  • Strange, works for me. Do you hav any diffrences in your code? – robbannn Sep 11 '14 at 14:22
  • Nope, I threw it in there just like that. I had to compile with the -std++11 modifier or whatever the newest one is, since it had issue with the ":" in the loop. Otherwise it's exactly the same. – zzzzzzzch Sep 11 '14 at 14:25
  • I don't have much time to try things out now, or read about stuff, but try placing a `cin.get();` statement right aftr the `for`-loop's closing `}`. I have a vague memory of it clearing the input-streams buffer from newlines. That might be the problem, try it and/or read about it. – robbannn Sep 11 '14 at 14:37
  • Have yoy reached any sucess? – robbannn Sep 11 '14 at 17:39
  • Alright, it worked but for some reason it's outputting the last line in the file twice. Still using your code. There's still exactly 20 ints and two strings at the beginning btw. Maybe it's the for parameters? The auto &k: scores_tem? – zzzzzzzch Sep 11 '14 at 19:00
  • Or wait no, it would have to do with the `!eof` parameter in the while loop. Any better way to increment this? – zzzzzzzch Sep 11 '14 at 19:04
  • Have you tried stepping through your program to see axactly what happens? – robbannn Sep 11 '14 at 19:06
  • Not at all. I'll run through it now. – zzzzzzzch Sep 11 '14 at 19:13
  • Okay, I was able to come up with a different solution, I'll post it as a reply. – zzzzzzzch Sep 11 '14 at 19:22
0
int 
main(int argc, char* argv[]) {

std::string last_name, first_name;
std::vector<int> scores;
int tmp;
std::ifstream filen ("input.txt");
while (filen >> first_name >> last_name) {



    scores.clear();  
    for (int i = 0; i < 20; i++)
        {
            filen >> tmp;
            scores.push_back(tmp);
        }                 
    std::cout<< first_name << " " << last_name << std::endl;
  }
}

So this is how I did it. The program takes in an argument hence the int main(int argc, char* argv[]). I then created two strings, one for each part of a name, and a vector for the scores of type int. I created a temporary integer location for the ones being read in.

Then I opened up the filestream from the input.txt and then made a while loop. The while loops parameters are such that WHILE I am reading in first a first name and then a second name, I clear the previous vector data. I then created a for loop to run through the rest of the numbers 20 times, assigning the next integer read in to be put into the scores vector.

Finally, I output the first and last names of each person as I'm going through the while loop. Hope this helps someone else.

zzzzzzzch
  • 29
  • 8
  • What do you mean by "The program takes in an argument hence the int main(int argc, char* argv[])"? By the way i found another solution that skips the eof() part. Check it out. – robbannn Sep 11 '14 at 19:38