Error with reading file in Linux - c++

In my program, I take two file names from the command line arguments using the following code:
ifstream routesFile (arv[1]);
ifstream citiesFile (arv[2]);
I then proceed to read through the file and grab the data. Both files are CSVs:
while(citiesFile.good()){
string city;
string country;
string xString;
string yString;
getline(citiesFile, country, ',');
getline(citiesFile, city, ',');
getline(citiesFile, xString, ',');
getline(citiesFile, yString);
...
}
When I do this in Visual Studio using hard-coded file names, it works fine. When I use the command line argument in linux after using g++, it can open the files correctly but after that it has a lot of errors. To test the file reading, I printed out some of the read values which resulted in
terminate called after throwing an instance of 'std::out_of_range'
what(): map::at
hereELF
Òœc½Å¹jn!ýô (EÕL˜C
The appearance of here is due to actually being printed in the program. It doesn't arise from the error, I manually printed it to test the code.
It seems to not be able to read the data correctly. In the file for citiesFile, there are always 4 values per line, each separated by a single command, no spaces, and a new line character separates lines in the file. As I said above, it works fine in Visual Studio so I don't think it's a problem with the actual data, just reading it.

Linux and window has different new line symbol. Linux '\n', windows '\r\n'. If you just copied the file into linux, you need to handle these in your program. You can look at Mixing cin and getline under Linux and Windows as a reference.

If you simply moved the Windows files to Linux, check out the tool dos2unix to convert the file and fix the line endings. "EOL" in your output is a sign that something might be wrong with the endings.
http://www.linuxcommand.org/man_pages/dos2unix1.html

Related

Is there a way to use getline() with an external text file then get control back for cin to take input from console?

I am new to C++ and wondered of there is a way to use just standard iostream to read in an input file (from using debugging properties: < filename) or other then get control back to the console to input something else later with cin.
I separated the file read part into a different function but it seems when I specify in the project properties the command to grab the file contents line by line with getline() it skips over any cin commands I issue later.
I'm sure this could just be a setup issue or I am may need to break it off into another program in the project somehow? This is a console app but surely there is a way to do both in the same project?
I have read that you can't use both cin and getline together but how does one input a file then go ask for more info from the user in a C++ app using visual studio?
Separate program and functions for the file read
'int lineIter = 0;
cin.getline(rowData, arraySize); // Grab first row of data
while (!cin.eof()) {
// output each row of data to screen:
cout << rowData << endl;
}
///// Increment for next ROW
lineIter++;
cin.getline(rowData, arraySize);'
Then later how do I go back to being able to use cin or other to get input from user?
I tried many variations of below later:
'cin.clear();
cin.ignore(arraySize);
cin >> selectR[b];'
and other variations of getline() but none stop program execution and I can't get them to do anything except try to read the file again.
I am using VS 2019 Community Edition
I don't really understand what you're trying to achieve here.
Currently, the way you read your external file is by changing std::cin's "source" from the console to the given file ; this change is made outside your program, at the debugger's level. So you will not be able to change the source back to the console from the program itself. (You might be able to do from the debugger while it's running though).
If you want to read external files and still be able to use std::cin normally, why not using std::fstreams ?
On the other hand, if you absolutely have to pass the file to the program through std::cin, you should keep it default and simply copy-paste your file in the console. Be careful though : since the file probably contains newlines, you will not be able to use those as end of input, so you'll have to design another way for the program to reckognize the end of the file (two consecutive empty lines for example).

C++: getline freezes at end of file

I want to read in one file line-by-line and output each line I read to a new file. In this code, cin has been redirected to refer to the input file, and cout has been redirected to refer to the output file.
The loop successfully writes every line in the file, but then it gets stuck on the final getline call. As a result, "Done" is not written to the file and the program does not terminate.
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
while(getline(cin, line)) {
cout << line << endl;
}
cout << "Done";
return 0;
}
Strangely, if I forcibly terminate the program, it seems to suddenly execute as desired, with "Done" being written.
Can someone point me in the right direction? Is there a flaw in the code, or is this some external configuration issue?
Notes: The input file in question ends with a newline character. Also, I do not want to use any includes besides these two.
The code should terminate on end of file (EOF) or any sort of file error. (The getline being called is:
http://en.cppreference.com/w/cpp/string/basic_string/getline
It returns the cin istream and then invokes its boolean conversion operator:
http://www.cplusplus.com/reference/ios/ios/operator_bool/
that checks if badbit or failbit is set on the stream. The failbit state should be set when a read is attempted with the stream already at EOF, or if there is an error.)
Per the comments above, it seems like this does work when the code is run from the shell directly. My guess is Eclipse is doing something complicated where it either intentionally sends the file into the program and then switches to an interactive input mode, or has a bug in which it doesn't close its end of a pipe or pty/tty it is using to send input to the program. (I.e. Eclipse is not binding stdin directly to the file itself in running the program.)
If one wanted to debug it further, one could look at the process state using tools like lsof. (Assuming a UNIXy system.) Might also be worth raising the issue in an Eclipse forum. The IDE is not my area of expertise.

Reading of text file in Ubuntu has extra //r

I am porting a program created in C++ from MS Studio to Ubuntu . The program works fine except when it reads from a text file .
My text file consists of lines of information seperated by the delimiter :
General Manager:G001:def
Customer:C001:def:Lim:Tom:Mr:99999999:zor#hotmail.com:Blk 145 B North #03-03 Singapore 111111
Read method
while (getline(afile,line,'\n')) //read line and store string in variable line
{
stringstream ss(line);
string s;
while (getline(ss,s,':'))
{
word.push_back(s);
}
word.clear();
}
On Windows platform , it is stored correctly as def
However on Ubuntu platform , it is stored as def\\r
It works fine for Customer Record but gives problem for General Manager
I know it has something to do with Carriage return but I am not sure how to resolve it
If the text file was created on Windows, you can use the dos2unix command to remove the extra \r's from the file. The command is simply dos2unix filenamegoeshere

C++ ofstream, printing without CRLF

I have a C++ code I am running in Linux with wine. I think this is actually part of the problem.
Usually, when I do something like this in a native Linux C++ program:
ofstream fout;
fout.open("myfile.txt")
fout<<"blah blah"<<endl;
fout<<"blah blah 2"<<endl;
fout.close;
The file is standard ASCII text. However, in the code I an running under wine, myfile.txt is now ASCII text with CRLF line terminators.
This is a problem because if I want to read the file using a native Linux C++ code running on the same machine, the CRLF line terminators really mess up a lot of the file handling and parsing.
Is there a way to get the code running under wine to output files without CRLF line terminators and in a fashion that I can read it using the native Linux C++ code on the same machine?
You could open the file in ios::binary mode. This doesn't, strictly speaking, mean that it's a binary file [any more than any other file is "text", since all files are binary]. Binary in this context just means "don't muck about with the stuff inside the file by interpreting characters as special, add or remove any characters, etc.
Or when you copy the file to Linux, use dos2unix myfile.txt to convert it from "dos" (and Windows) format to "unix" style text file.

when would failbit be set while executing a getline function call in c++

when would getline in c++ fail?
I have a big snippet of code which I am unable to paste in its entirety for multifarious reasons. I am trying to read from a file , which I know exists and contains data, using getline in C++. But getline fails returning error 123-invalid name(output of getlasterror). I looked up the error code which baffles me even more.
I do error check while opening the file. So I am positive that I have the handle to the file.
Please bear with me for not pasting the code. I am new to c++ and especially in windows. Any suggestions or insights about getline would help. I am trying to read a file which is dumped by a compiler.
This is an extract from the code
ifstream inFile("C:\...\ash.txt",ios::in);
string singleLine;
getline(inFile,singleLine);
singleLine is empty ! I am doing something silly..pls point that out to me! appreciate it
IMPORTANT EDIT:
I checked for the ios members and found that fail bit is set. Why would the fail bit be set? the file does exist and also I was wondering if how windows exposes file extensions could cause a problem . That doesnt seem to the problem. What am i missing?
GetLastError only tells you about Win32 API calls, which std::getline is not.
Check the members of the iostream that failed, e.g. rdstate().
Calling ios::exceptions(eofbit | failbit | badbit) before getline and catching the resulting exception might or might not get you a more descriptive error message.
If the fail bit is set, it is probably because you didn't successfully open the file. Check whether ifFile.is_open() returns true; if not, then then probably indicates that the file is not open correctly. You might not have permissions, or you may need to escape the string properly, or the file may be locked.
You should also check if fail is set both before and after the call to getline. If it's before, that probably means that the file isn't open. If it's after, it could mean that the file is empty.
It may be the case that Windows is hiding the true file extension from you. The file name might actually be named ash.txt.txt, for example, if you have Explorer configured to hide file extensions. That might be worth investigating if the file isn't open.
Do you need to escape the backslashes in the file path?
It failed to open the file.
This is becuase you did not specify the correct path.
This is because you used the ancient windows convention of \ as a path separator.
Which also happens to be the escape character in C.
Which is why Windows lets you use / as a path separator (and has done for over a decade) because the use of '/' is so error prone.
Your path should be:
ifstream inFile("C:\\...\\ash.txt");
// Or my preference
ifstream inFile("C:/.../ash.txt");
Or even better use boost.
Getline IIRC is meant for c_strings and the string is the first argument, not the second.
http://www.cplusplus.com/reference/iostream/istream/getline/
You're attempting to use a normal string, which (I could be wrong) doesn't work with getline.