ulug toprak ulug toprak - 25 days ago 11
C++ Question

Trying to insert user defined objects into a vector while i read values from a directory of files

I am trying to open a directory and read the 4 text files with different number of iterative and selection statements.
having trouble with the while and for loop something going wrong but i can't figure it out. pretty new to c++

#include <iostream>
#include <dirent.h>
#include <string>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <fstream>

using namespace std;

typedef struct { // typedef for all the counters
string fName; // to store the file name
int countFor = 0;
int countIf = 0;
int countWhile = 0;
int countSwitch = 0;
int countElse = 0;
int total = 0;
} counters;

string filepath;

static const int S = 4;

vector<counters> files(S);
DIR *dp = NULL; //typedef in dirent.h
struct dirent *d;

void print();

int main()
{

cout << "************************Welcome!*****************************" << endl;
cout << "This program is designed to check plagiarism using simple" << endl;
cout << "measures between the files within the directory entered by user " << endl;
cout << "*************************************************************" << endl;

string directory;
cout << "Please enter a directory: \n"; // enter test for testing
getline(cin, directory);

dp = opendir(directory.c_str());
if (dp == NULL)
{
cout << "Error! opening the directory: " << directory << endl;
system("pause");
exit(0);
}
while ((d = readdir(dp)) != NULL)
{
filepath = directory + "/" + d->d_name;

if (!strcmp(d->d_name, "..") || (!strcmp(d->d_name, ".")))
{
continue;
}
ifstream myFile(filepath.c_str());


for (int i = 0; i < 4; i++)
{
myFile.open(filepath.c_str());

string read;

files[i].fName = d->d_name;

while (myFile >> read)
{
if ("for" == read)
{
files[i].countFor++;
files[i].total++;
}
else if ("while" == read)
{
files[i].countWhile++;
files[i].total++;
}
else if ("if" == read)
{
files[i].countIf++;
files[i].total++;
}
else if ("switch" == read)
{
files[i].countSwitch++;
files[i].total++;
}
else if ("else" == read) {
files[i].countElse++;
files[i].total++;
}

}

myFile.close();

}
}
print();
system("pause");
return 0;
}

void print() {
ofstream testFile;
testFile.open("Results.txt");

testFile << setw(20) << "Document Name"
<< setw(20) << "If Statements"
<< setw(20) << "Switch Statements"
<< setw(20) << "For Loops"
<< setw(20) << "Else Statements"
<< setw(20) << "While Loops"
<< setw(20) << "similarity \n";
for (int i = 0; i < 4; i++)
{
testFile << setw(20) << endl
<< setw(20) << files[i].fName
<< setw(20) << files[i].countIf
<< setw(20) << files[i].countSwitch
<< setw(20) << files[i].countFor
<< setw(20) << files[i].countElse
<< setw(20) << files[i].countWhile
<< setw(20) << files[i].total << "\n";
}
testFile.close();
}


here is the out put
Document Name If Statements Switch Statements For Loops Else Statements While Loops similarity

read4.txt 0 0 0 0 0 0

read4.txt 10 4 11 15 1 41

read4.txt 10 4 11 15 1 41

read4.txt 10 4 11 15 1 41

Answer

Read this part:

while ((d = readdir(dp)) != NULL)
{
    filepath = directory + "/" + d->d_name;

    if (!strcmp(d->d_name, "..") || (!strcmp(d->d_name, ".")))
    {
        continue;
    }
    ifstream myFile(filepath.c_str());


    for (int i = 0; i < 4; i++)
    {
        myFile.open(filepath.c_str());
        string read;

        files[i].fName = d->d_name;

You're reading (and storing the results for) each file four times, and you're only keeping the (four) results for the last file in the directory.
The reason that you got all zeros for the first iteration is that the file was already open when you tried to open it - the constructor took care of that - and this put the stream into its "failure state", so the subsequent reads all failed.
Your explicit closing of the stream in the loop lets later iterations succeed.

Don't hardcode the number of files, use push_back to add to the vector.

Something like this:

while ((d = readdir(dp)) != NULL)
{
    if (!strcmp(d->d_name, "..") || (!strcmp(d->d_name, ".")))
    {
        continue;
    }

    std::string filepath = directory + "/" + d->d_name;
    std::ifstream myFile(filepath);
    counters c;
    c.fName = d->d_name;

    string read;
    while (myFile >> read)
    {
        if ("for" == read)
        {
            c.countFor++;
            c.total++;
        }
        else if ("while" == read)
        // ... and so on - your code with 'c' instead of 'files[i]'
    }
    files.push_back(c);
}
Comments