0

im trying to make a program in c++ which would work through a txt file, and if there are duplicates in the numbers in this file, dont print them and only print out the numbers which appear once.

this is the code i've got. but what happens is it prints the file out, then prints out the second line again instead of looking for dublicates...

can anyone show me where im going wrong. fairly new to c++

// array.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
    int array[100]; // creates array to hold numbers
    short loop=0; //short for loop for input
    string line; //this will contain the data read from the file
    ifstream myfile ("problem3.txt"); //opening the file.
    if (myfile.is_open()) //if the file is open
    {
        while (! myfile.eof() ) //while the end of file is NOT reached
        {
            getline (myfile,line); //get one line from the file
            array[loop] = line;
            cout << array[loop] << endl; //and output it
            loop++;
        }

        for (int i = 1; i < loop; i++)
        {
            bool matching = false;
            for (int j = 0; (j < i)&& (matching == false); j++)
            {
                 if (array[i] == array[j]) 
                      matching = true;
             }
             if (!matching) 
                cout<< array[i] << " "
        }   
        myfile.close(); //closing the file
     }
      else 
         cout << "Unable to open file"; //if the file is not open output
     system("PAUSE");
     return 0;
 }
taocp
  • 22,020
  • 6
  • 46
  • 60
Andrew Glass
  • 401
  • 2
  • 6
  • 18
  • You're saying this compiles? – Benjamin Lindley Apr 24 '13 at 02:37
  • 2
    You're commenting lines that need no explanation. I don't know if maybe your teacher is insisting you do this, but as soon as the class is over please stop. Code should explain itself - comments should only be used when it's impossible to write self-explanatory code for your problem or efficiency is an issue and you've used an unintuitive algorithm that needs explanation. `if (myfile.is_open()) //if the file is open` is really redundant - you're just repeating what the code already says. – exists-forall Apr 24 '13 at 02:37
  • yeah it complies, it would print the numbers in the file, then print a second line with the 2nd line of numbers, but wouldnt remove the duplicates. anyone know how i could fix this? – Andrew Glass Apr 24 '13 at 02:41
  • 1
    You call `system("PAUSE")` ([a WTF in its own right](http://www.gidnetwork.com/b-61.html), but that's another story) before actually writing the output. You have no `cout << flush;`. – David Schwartz Apr 24 '13 at 02:53
  • A few suggestions: 1) read http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong/5605159#comment23094105_5605159 to see why `while(!eof())` is wrong. 2) use a set to record numbers already seen - for each number read only print it if it's not already in the set. 3) listen to Mr Schwartz. – Tony Delroy Apr 24 '13 at 02:59
  • its late here in the uk and my head is abit wrecked. what way should i be populating my array from the file, forgetting i want duplicates. if i even got that i could probably get the duplicates sorted out myself – Andrew Glass Apr 24 '13 at 03:07

2 Answers2

1

At least one error: array is declared as an array of integers, you are reading string line and assign string to int directly below:

 getline (myfile,line); //^^line is string, array[i] is int
 array[loop] = line;

You may try to read those lines in a vector then call std::unique to make the vector unique and print them out. You file lines are not necessarily lines of integers, so store them in an integer array may not work.

You may try:

#include <vector>
#include <string>
#include <algorithm>
#include <iterator> 

int main()
{
    std::vector<std::string> data;
    ifstream myfile ("problem3.txt");
    string line;
    //if not required to use array
    while (getline(myfile, line))
    {
      data.push_back(line);
    }

    std::vector<std::string> data(dataArray, dataArray + 100);

    myfile.close();
    std::sort( data.begin(), data.end() );
    data.erase( std::unique( data.begin(), data.end()), data.end() );
    //now print vector out:
    std::copy(data.begin(), data.end(), ostream_iterator<string>(cout, " \n"));
    return 0;
}
taocp
  • 22,020
  • 6
  • 46
  • 60
  • Calling `std::unique` by itself is almost never correct. You need to do something with its return value, otherwise you've got a series of indeterminant values, and you don't know where it starts. Generally, passing it, along with the end iterator, to the `erase` member function of the container is the desired functionality. Similar to what you would do with `std::remove` or `std::remove_if`. – Benjamin Lindley Apr 24 '13 at 03:02
  • @BenjaminLindley thanks, yeah, I think I missed something, thanks! will update it in a few minutes. – taocp Apr 24 '13 at 03:05
  • @BenjaminLindley updated, would you please take a look whether it is what you meant? thanks a lot! – taocp Apr 24 '13 at 03:09
  • Yes, that's correct. You even added the sort in there, which is a prerequisite for `std::unique` that I failed to notice wasn't there before. – Benjamin Lindley Apr 24 '13 at 03:13
  • @BenjaminLindley thanks a lot for pointing that out, I learned and refreshed memory again. – taocp Apr 24 '13 at 03:15
  • when i try to compile this it says comp and sortComp are not declared and wont compile? – Andrew Glass Apr 24 '13 at 03:16
  • @tacp how do you mean? i put it all into the main bar the #includes – Andrew Glass Apr 24 '13 at 03:18
  • how would i do this if i was to only use arrays though, not that im not grateful for the great inputs. its just i've been asked to use an array so would prefer to put the numbers into an array and find the duplicates and just print out the numbers which only occur once? – Andrew Glass Apr 24 '13 at 03:23
  • when i try to compile that i get data is underfined when its referring to the data[i] – Andrew Glass Apr 24 '13 at 03:26
  • yeah sorry i meant visual studio – Andrew Glass Apr 24 '13 at 03:30
  • aye i did throw that in when noticed it wasnt there. still get the undefines when referring to the data[i] in the bool comp and bool sortComp – Andrew Glass Apr 24 '13 at 03:34
  • @tacp yeah that sorted that error, but course with my luck i get threw a different one: error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::basic_string<_elem>' (or there is no acceptable conversion) – Andrew Glass Apr 24 '13 at 03:40
  • yeah compiles grand, but it wouldnt remove the duplicates? – Andrew Glass Apr 24 '13 at 03:56
  • weird. when i run it it would print out the list but wouldnt delete the duplicates? – Andrew Glass Apr 24 '13 at 04:06
  • @AndrewGlass it worked here: http://ideone.com/c4rQQp#view_edit_box. i change array size to 5 and read from stdin, you will see that it works for both ways of outputs. let me know if you cannot view it. – taocp Apr 24 '13 at 04:14
  • would it be due to how the numbers are list in the txt file? they are just separated by spaces? – Andrew Glass Apr 24 '13 at 04:19
  • when i tried that it throws up: no instance of overloaded function "getline" matches the argument list. and that number is undefined – Andrew Glass Apr 24 '13 at 04:31
  • number and data are undefined – Andrew Glass Apr 24 '13 at 04:37
  • i donno what it done there but when i output it it just printed out a load of weird symbols lol – Andrew Glass Apr 24 '13 at 04:45
0

Instead of using nested for loops, I would suggest using an array to keep count of how many times a certain integer shows up. You can then loop over that once and only print the integers with a count of 1.

One of the problems with your nested for loops is since you're only checking for duplicates as long as j < i, you might print an integer even though it has a duplicate later in the array. You simply have to check the whole array to make sure that there are no duplicates.

If you still want to try, you probably want to do something like this:

for (int i = 0; i < loop; i++) // start at 0!
{
   bool matching = false;
   for (int j=0; j<loop; j++) { // check the whole array for duplicates!
       if (i != j && array[i] == array[j]) {
           matching = true;
           break; // instead of complicated condition in for loop
       }
   }
   if (!matching) cout << array[i] << " ";
}  
Victor Sand
  • 2,220
  • 12
  • 30