ifstream

We are trying to open a set of files listed in a txt file called "model.txt". Once we open that file each line is the name of other file with the dataset.
The problem is that it is not openning when we read the name from the file, but it opens when we set the name of the file manually. We cyhecked the path and the file existence and locks. It is working in visual strudio 15 (Windows) but it is not working in linux (We also checked the slashes "/" and "\\").

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  int main(int argc, char* argv[])
{
	string pasta = "data/";
	string mm="modelos.txt";
        string nomeArquivo = "";
	ifstream arquivoModelos(string(pasta + mm).c_str());
	
	ifstream nn;
	while (getline(arquivoModelos, nomeArquivo)) {		
        string pFile=string(pasta + nomeArquivo); // It does not open!
        // string pFile=string(pasta + "exemplo1.dat" ); // It does open! 
        cout << pFile.c_str() <<endl;
		nn.open(pFile.c_str());
		if (nn.good())
		cout << "Good" << endl;
		else
		cout << "Bad" << endl;
		
	}
	cout << "Final do processamento.\n";
	arquivoModelos.close();
	return 0;
}


It makes non sense since the file models.txt contains exactly the same value, it is "exemplo1.dat".

Thanks.
David
Last edited on
Hello dcaro,

You are missing the header files in your code.

With what you have posted you are not using "argc" or "argv", so they are not need int main() will work just fine.

You talk about an input file that contains other file names you will need to open at some point. It would help if you include this file with your post so everyone will be working with the same information. If you feel it is to large then a fair sample will work.

Line 5. The (= "";) is not needed to initialize the variable as a "std::string" is empty to start with and contains nothing when defined.

On line 6. The use of "string" is not needed. Just "pasta ++ mm" will work just fine. And from C++11 on the ".c_str()" is no longer needed. A "std""string" will work.

Line 10. You say "It does open!". What does not open. It looks like you are defining "pFile" as a "std::string" and setting it equal to "string(pasta + nomeArquivo)". Again the "string" is not needed here only "pasta + nomeArquivo" as both these variables have already been defined as "std::strings".

For lines 12 on I will have to do some testing.

Through out the program the use of ".c_str()" is not need if you have included the header file "string" and your compile is up to the C++11 standards or beyond.

For now this is what I see from just looking at the code. I will load up the program and give a test to see what else I can find.

Hope that helps,

Andy
What does this print when it doesn't open the file?

 
cout << '[' << pFile.c_str() << "]\n";

Note that I added some brackets so you can see if there's any extra spaces at the ends.
It's possible that an extra space at the end will fail with linux (I'll test that in a minute) but work with windows.

EDIT: As I suspected, an extra space at the end of the string causes it to fail in linux. Maybe windows ignores spaces at the end of the string for a filename.
Last edited on
@tpb

For me it printed [data/File1.txt] until I changed it to just the file name so I did not have to create that directory.

But I did make changes to the program.

Without seeing the input I do not know what is being read and how it is coming out. What I set up is working.

Andy
@Andy, but do you understand my hypothesis? If there's an extra space at the end of the filename in modelos.txt, then maybe it works on windows (which possibly ignores spaces at the end of a filename) and doesn't work on linux. I tested the linux case and it fails with an extra space. I can't presently test the windows case.

Maybe he should trim the filename read in from modelos.txt:

1
2
3
4
5
string trim(const string& s) {
    size_t start = s.find_first_not_of(" \t");
    if (start == s.npos) return {};
    return s.substr(start, s.find_last_not_of(" \t") - start + 1);
}

Last edited on
@tpb,

Yes I understand and just tested it in Windows and the space at the end of the file name made no difference.

Either there is a problem opening the file "modelos.txt" or what is in the file is the problem.

Andy
@tpb,

In the input file I tried adding a space at the end it made no difference, but a "\t" did not work in Windows.

Andy
@Andy, I think he said it works on windows and doesn't work on linux. A single space at the end of the filename will cause exactly that according to our tests.
Maybe use perror to get a proper error message
http://www.cplusplus.com/reference/cstdio/perror/
Attached, those tests you asked.

Headers:
1
2
3
4
5
#include <iostream>
#include <vector>
#include <fstream>
#include <ctime>
#include <string> 


we did the corrections about the unneeded .c_str(); in 5,6,7,12.

we modified the code to print an output between [], to check where it is going wrong.

As we said the file modelos.txt was successfully opened. In windows we did not have any trouble but in linux something is weird.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main(int argc, char* argv[])
{


	string pasta = "data/";
	string fnamestr="exemplo1.dat";
	ifstream arquivoModelos(string(pasta + "modelos.txt"));
	ifstream teste1;
	ifstream teste2;
	string nomeArquivo;
	while (getline(arquivoModelos, nomeArquivo)) {
		cout << "Executando arquivo: [" << nomeArquivo << "]" << endl;
		cout << "Executando arquivo: [" << fnamestr << "]" << endl;
                teste1.open(nomeArquivo); // this one is not working
                if(teste1)
                      cout << "File opened - while reading name from file" << endl;
                else
                      cout << "Error openning file - while reading name from file" << endl;
                teste2.open(fnamestr); // this one is working
               if(teste2)
                      cout << "File opened - while reading name from declared variable" << endl; 
               else
                       cout << "Error openning file - while reading name from declared variable" << endl;
	}
	cout << "Final do processamento.\n";
	//getch();
	return 0;
}


The given output was: https://ibb.co/mxO1Lq
We noticed that the output for the string read from the file and the string read declared directly was different.

]xecutando arquivo: [exemplo1.dat <--- We think something is happening here.
Executando arquivo: [exemplo1.dat] <--- This one is opening the file normally.

The text in the file modelos.txt has not format, it is plain and it has anything at the end of line. So, this error is not making any sense to us. https://ibb.co/haecRV

David
Last edited on
It was solved removing the last character of nomeArquivo.

Thanks a lot!

David.
Topic archived. No new replies allowed.