ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am using ifstream to open a file, read a string then open a file which has that string in it.
for example:
I open "allroad.con" which has, say, "Bonavista" in it. I then open a file called "Bonavista.con". The problem is when I open Bonavista.con (I used is_open() to confirm that opening worked) the first read I try fails. I know the number 4 is on the first line so use inData >> a; where 'inData' is my ifstream and 'a' is an int.
Any ideas why the read is failing? It works fine for the first file which is almost exactly the same.
Here are a few lines, "routeName[i].getName()" gets the name say "Bonavista". I had to do some string-char conversions because using getline I get a std string so I converted it because inData.open cannot use a std string.
> inData.open(const_cast<char*>(file.c_str()));
you dont need the const_cast.. just use file.c_str() .
>> Any ideas why the read is failing? It works fine for the first file which is almost exactly the same.
its logic somewhere else .. inData.fail() is saying that the read operation failed.. which probably in this case means you are opening the wrong file or the file is empty?
if needed post some surrounding code for testing..
I took out const_cast<char*>...works but same error still.
Will not take in the value.
I also tried getline(inData,nextLine); nextLine being a string, but it wouldn't even take in the string. I also diverted the program to read another file with just "8" in it. and it wouldn't take the "8" in.
xhi-> when I remove const_cast do I still need the <char*>?
const_cast<T>(x) is a parameterised operator. It takes a value, x, and changes it to type T by adding or removing const.
You can't just write (<char*>), because it would have no effect; you are trying to refer to a char* specialiation without a template.
std::string::c_str() will get you a pointer to the string of type const char*, which should be suitable for passing to ifstream:pen(const char *s, std::ios_base:penmode mode = std::ios_base::in);
So if this doesn't work:
inData.open(file.c_str());
Then you have a far more serious problem (possibly a bug in your compiler's implementation of the standard libraries). [Edit: This problem may or may not be related to the problem in your post].
[Edit: This is wrong:
In fact, I don't think you even need the .c_str(), because there's an implicit conversion to const char* in std::string, so you should be able to say:
C++ has a "default" conversion from char * to string but not the other way around that I'm aware of and so yes the c_str() or data() methods are required.
It is very unlikely that there is a bug in the compiler, possible a corrupt installation but that is quite different.
But check the file permissions and maybe post a little more of the code.
Which OS are you using?
cout the file.c_str(); what do you get?
The following complete program opens a file named allcon.con, reads a filename from the file, closes the file, then opens a file using the name that was read.
allcon.con:
Code:
bonavista.con
bonavista.con
Code:
4 (gridpoints)
Bonavista to St. John's
437 237 A Near St. John's
434 233 B Near Whitbourne
429 234 C Near Clarenville
428 240 D Near Bonavista
The complete source code of the program:
Code:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
static string get_name_of_file_to_open(ifstream&);
static void read_and_display_file(ifstream&);
int
main()
{
ifstream file("allroad.con");
if(!file)
{
cerr << "Failed to open file allroad.con" << endl;
return EXIT_FAILURE;
}
const string& filename = get_name_of_file_to_open(file);
file.close();
file.open(filename.c_str());
if(!file)
{
cerr << "Failed to open " << filename << endl;
return EXIT_FAILURE;
}
read_and_display_file(file);
return EXIT_SUCCESS;
}
static string
get_name_of_file_to_open(ifstream& file)
{
string str;
/* We assume the name of the file we want
to open is the first string in this
file and we assume our current reading
position is at the beginning of the file. */
file >> str;
return str;
}
static void
read_and_display_file(ifstream& file)
{
int num = 0;
string str;
/* We know the first line is a number and a single word. */
file >> num >> str;
cout << num << " " << str << endl;
/* We know the second line is a string (that contains spaces),
but we're actually still at the first line, so we need to
skip to the second line by calling getline(). Then we call
getline() again to read the second line. */
getline(file, str); /* Skip to the second line. */
getline(file, str); /* Read the second line. */
cout << str << endl;
int a = 0;
int b = 0;
char c = '\0';
/* Now we loop the number of times as stated at the beginning of
the file. The line all have the following format:
int int char some_string_that_may_contain_spaces */
for(int i = 0; i < num; ++i)
{
/* First we read the two ints and the char. */
file >> a >> b >> c;
/* The we read the remainder of the line into a std::string. */
getline(file, str);
cout << a << " " << b << " " << c << " " << str << endl;
}
}
$ ./foo.exe
4 (gridpoints)
Bonavista to St. John's
437 237 A Near St. John's
434 233 B Near Whitbourne
429 234 C Near Clarenville
428 240 D Near Bonavista
The gridpoints are stored in separate int variables and the single upper-case character is stored in a char and the remainder in a std::string.
I can open Allroad.con and get the data correctly no problem, so instead of opening the Bonavista.con the second time I tried to see if opening the Allroad.con file and that never worked. It's like I can't open two files??? if there is such a thing.
Here is the code:
Code:
include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <string.h>
#include "ARoute.h" //used later in the program
using namespace std;
int main (){
ifstream inData;
int noRoutes;
ARoute* routeName;
//temporary holds for setting characteristics of classes below
string nextLine;
int a,b;
char letter;
inData.open("c:\\Wxsystem\\Roadgram\\Commands\\AllRoad.con");
if (!inData.is_open()){
Error("AllRoad.con failed to open");
return -1;
}
inData >> noRoutes; //gets number of routes
if (inData.fail()){
Error("Number routes unspecified");
return -1;
}
routeName = new ARoute[noRoutes]; //creates array to store route data
inData.ignore(100,'\n'); //skips remainder of line
for(int i=0; i<noRoutes; i++){ //gets route names
getline(inData,nextLine);
if (inData.fail()){
Error("Retrieving routes");
return -1;
}
routeName[i].setName(nextLine);
}
inData.close();
//Start major loop for each route Z
for(int Z=0; Z<noRoutes;Z++){
string file = "c:\\Wxsystem\\Roadgram\\Commands\\" + routeName[Z].getName() + ".con";//file to open
inData.open(file.c_str()); if (!inData.is_open()) {
Error(file+" failed to open");
return -1;
}
inData >> a; //gets number of grid points in route
if (inData.fail()) {
Error(file+ "\nFailed to get number of grid points");
return -1;
}
routeName[Z].setNumGridPts(a);
inData.ignore(100,'\n');
getline(inData,nextLine); //gets grid point description
if (inData.fail()) {
Error(file+"\nFailed to get description");
return -1;
}
routeName[Z].setDescription(nextLine);
for(int j=0; j<routeName[i].getNumGridPts(); j++){ //gets each grid points data
inData >> a >> b; //gets x and y directional grid points
if (inData.fail()) {
Error(file+ "\nFailed to get either of the grid numbers");
return -1;
}
routeName[Z].setxy(a,b,j);
inData >> letter; //gets reference letter of grid point.
if (inData.fail()) {
Error(file+"\n Failed to get grid point reference letter");
return -1;
}
routeName[Z].setGridLetter(letter,j);
getline(inData,nextLine); //gets the name of grid point
if (inData.fail()) {
Error("Failed to get grid point name");
return -1;
}
routeName[Z].setGridName(nextLine,j);
}
inData.close();
}
Last edited by BenScaplen; 02-01-2006 at 06:06 AM.
error C2676: binary '>>' : 'class std::basic_ostream<char,struct std::char_traits<char> >' does not define this operator or a conversion to a type acceptable to the predefined
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.