Ok so this is really annoying me...I'm trying to go through and parse a bunch of .csv files for content but I can't get past trying to open them.

I want to read the directory contents and then open the specified file. I have the code working so it prints the directory contents successfully but when it tries to open the file it can only open the first 4 and then fails on the rest. If I hard code the filenames of the files it "FAILS" on (i.e. inFile.open("filename.txt")) it works just fine.

Any suggestions? Oh and I did try reading the entries from a list.txt but I can't get that to work either. My guess is the null character or something is interfering with the attempt to open it but I can't figure out how to work around that...I can do it in perl just not C++ :(

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

using namespace std;

int main()
{
   DIR *dirp;
   struct dirent *entry;
   int pos;
   int linecount = 0;

   if(dirp = opendir("C:\\csvfiles\\"))
   {
      while(entry = readdir(dirp))
      {
         //printf("%s\n", entry->d_name);  //prints the files in the directory
         string temp = entry->d_name;
         if (temp.length() > 2)    //skips over the . and .. entries
         {
            ifstream inFile;           //creates a fstream object inFile
            inFile.open(entry->d_name);    //opens the file
            if (!inFile.is_open())                 //if file wasn't opened
            {
               cout << "Failed to open " << entry->d_name << endl;
               // return 1;
            }
            else 
            {
               cout << "Successfully opened " << entry->d_name << endl;
             }
             inFile.clear();
             inFile.close();    
         }  //end of while file exists
      }
      closedir(dirp);
   }     
   return EXIT_SUCCESS;
}

This is my output...

C:\bom\Debug>bom.exe
Successfully opened 5A40 Combo.csv
Successfully opened 5A40 Head.csv
Successfully opened 5A80 Combo.csv
Successfully opened 5A80 Head.csv
Failed to open 5C1.csv
Failed to open 5C1A.csv
Failed to open 5C1x2.csv
Failed to open 5C3.csv
Failed to open 5C3P.csv
Failed to open 5C5.csv
Failed to open 5E3 Head.csv
Failed to open 5E3.csv

Dani AI

Generated

Quick summary and root cause: as discovered (and demonstrated), the directory entry returned by the OS is just the file name (the d_name field) — not a full path — and opening a bare name uses the process current working directory, so files that happen to live in that folder open while others fail. Also, the memory for a readdir() result can be overwritten by the next call, so copy names if you need them beyond the current iteration. (man7.org)

A more robust, modern approach is to use the C++ filesystem library (C++17+) and work with absolute paths or std::filesystem::path objects; that removes hand-joining mistakes and makes intent explicit. Example pattern (C++17+):

#include <filesystem>
#include <fstream>
#include <iostream>

namespace fs = std::filesystem;

for (auto const& e : fs::directory_iterator("C:/csvfiles")) {
    if (!e.is_regular_file()) continue;
    std::ifstream in(e.path()); // path-aware constructor / open
    if (!in) std::cerr << "Failed: " << e.path() << '\n';
    // process file...
}

This relies on standard filesystem iteration and the ifstream overloads that accept path/string types. (en.cppreference.com)

Quick troubleshooting checklist and pitfalls to watch for:

  • Print the program working directory while debugging (std::filesystem::current_path()) so you know where relative names resolve. (en.cppreference.com)
  • Debugger vs. running the EXE: IDEs sometimes set a different working directory than the output folder — that’s why a few files in the debug folder opened while others didn’t.
  • On Windows watch for path-length and namespace issues (MAX_PATH, Unicode filenames); use the filesystem APIs or extended path prefixes when necessary. (learn.microsoft.com)

Bottom line: build absolute paths (or use std::filesystem and its path-joining), verify the working directory when debugging, and handle long/Unicode names if your environment needs them.

Recommended Answers

All 11 Replies

Member Avatar for Member #46692

what do you mean it fails?

fails = can't open the file. eventually i need to parse the file looking for specific information but i'm stuck since i can't actually open it. the only other way i've found is to hardcode the files into a static const char array...but there are 90 some files so that's not practical. i should be fine once i can get the files to open.

i just don't understand why 4 open correctly and the rest won't...

Member Avatar for Member #46692
#include <iomanip>
#include <iostream>
#include <dirent.h>
#include <fstream>
#include <string>

using namespace std;

int main()
{
   DIR *dirp;
   struct dirent *entry;
   int pos;
   int linecount = 0;

   if(dirp = opendir("C:\\csvfiles\\"))
   {
      while(entry = readdir(dirp))
      {
         //printf("%s\n", entry->d_name);  //prints the files in the directory
         string temp = entry->d_name;
         temp = "C:\\csvfiles\\" + temp;
         if (temp.length() > 2)    //skips over the . and .. entries
         {
            ifstream inFile;           //creates a fstream object inFile
            inFile.open(temp.c_str());    //opens the file
            if (!inFile.is_open())                 //if file wasn't opened
            {
               cout << "Failed to open " << entry->d_name << endl;
               // return 1;
            }
            else 
            {
               cout << "Successfully opened " << entry->d_name << endl;
             }
             inFile.clear();
             inFile.close();    
         }  //end of while file exists
      }
      closedir(dirp);
   }
   
   system("pause");     
   return EXIT_SUCCESS;
}

untested

Member Avatar for Member #46692

any joy?

it worked :) yay thanks! I guess I just needed to specify the entire path since I had variations of what you changed before (without the full path).

Thanks :)

Member Avatar for Member #46692

please can you mark this thread as solved.

so just curious...any idea why it would work for some and not all? i mean the code works now but i'm still a bit curious why it didn't work for everything.

Member Avatar for Member #46692

so just curious...any idea why it would work for some and not all? i mean the code works now but i'm still a bit curious why it didn't work for everything.

The reason why it worked on some is that you must have these files:

Successfully opened 5A40 Combo.csv
Successfully opened 5A40 Head.csv
Successfully opened 5A80 Combo.csv
Successfully opened 5A80 Head.csv

within your debug folder? I'm guessing.

Ok now I feel REALLY dumb... you were right, those files were in my debug folder. Thanks again. :)

Member Avatar for Member #46692

No probs sometimes you hit a brick wall and you miss the obvious.

You might wanna look into why I had to use c_str() for reading in the paths...

yeah I had discovered I had to use c_str() a while back but when i tried opening using inFile.open(temp.c_str())...but it didn't work (since i wasn't specifying the full path). i at least got error messages with temp.c_str() vs the compile error just using temp.

and for those who might wander across this thread....the method 'c_str()' will return a pointer to a null-terminated representation of the std::string's content.

anyways thanks again!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.