Comparing strings from a text file - c++

I am parsing a text file, and for some reason string::compare() isn't working as intended.
The text file: http://pastebin.com/raw.php?i=WZDWmb56
The read function (called from inside while loop):
string StopName = "***";
bool Person::ReadOnePersonFromFile(ifstream& fin)
{
getline(fin,m_name);
cout << m_name << endl;
if( m_name == StopName )
return false;
fin >> m_id;
fin.ignore(50,'\n');
return true;
}
Whenever "***" is reached, if( m_name == StopName ) doesn't return true. What is going on?
This function works on Windows (Visual Studio). I am currently compiling this on Linux. Does this have anything to do with how the text is stored?

It looks like you're comparing StopName rather than Stop in your code, so "***" isn't ever checked (assuming that Stop and StopName aren't the same thing).

Found my answer. I believe this is because of the way newline characters are encoded on Windows.
Windows: \r\n (CR + LF)
Linux: \n
Mac: \r
I had to convert my Windows text file to a Unix text file with dos2unix. The program works fine.

Related

ofstream not generating new lines in Windows subsystem for Linux

I'm trying to write a .dat file using Windows subsystem for Linux, but the fstream library seems to bypass every endline command.
Here is my code:
int main()
{
string fname = "DataSheet.dat";
ofstream fdata (fname.c_str(), ios::out);
fdata << "First line" << endl;
fdata << "Second line" << endl;
fdata.close();
return = 0;
}
I tried substituting << endl with << "\n" and modifying the ofstream command like showed there, but nothing worked; the output was always First lineSecond line instead of First line and Second line on subsequent lines.
Besides, the code works perfectly well when I print the output to video using cout command or when I compile and run it on cygwin.
Is it a problem of Windows subsystem for Linux or am I missing something important?
By a comment.
Try substituting << endl with \r\n
This is due to the differences in the line endings of linux and windows.
In windows you need to add a carriage return and then the new line character.
While in linux there is not need for the carriage return.
The problem comes from the fact that you are compiling for linux so std::endl places the linux version line ending but you are trying to view the output in windows.

C++ Go back a line

I'm writing a multiple lines system, like this:
string readLines(string x)
{
string temp = "a";
vector<string> lines(0);
string result;
while (1)
{
cout << x;
getline(cin, temp)
if(temp != "")
{
result = result + "\n" + temp;
lines.push_back(temp);
}
else
break;
}
return result;
}
Is working fine, but I want be able to edit the previous line, for example, I'm typing something like this:
Helo,
World
I want to back on helo and fix my typo. How can I do this?
There is no portable way to go back one line in C++.
You can go to the beginning of the line by printing \r, but moving to the previous line requires platform dependent code.
If don't want to use libraries like Curses, you can try ANSI escape codes. Depending on the terminal, cout << "\033[F" will move the cursor one line up.
On Windows, there is also the SetConsoleCursorPosition API.

How to ignore a character through strtok?

In the below code i would like to also ignore the character ” . But after adding that in i still get “Mr_Bishop” as my output.
I have the following code:
ifstream getfile;
getfile.open(file,ios::in);
char data[256];
char *line;
//loop till end of file
while(!getfile.eof())
{
//get data and store to variable data
getfile.getline(data,256,'\n');
line = strtok(data," ”");
while(line != NULL)
{
cout << line << endl;
line = strtok(NULL," ");
}
}//end of while loop
my file content :
hello 7 “Mr_Bishop”
hello 10 “0913823”
Basically all i want my output to be :
hello
7
Mr_Bishop
hello
10
0913823
With this code i only get :
hello
7
"Mr_Bishop"
hello
10
"0913823"
Thanks in advance! :)
I realise i have made an error in the inner loop missing out the quote. But now i receive the following output :
hello
7
Mr_Bishop
�
hello
10
0913823
�
any help? thanks! :)
It looks like you used Wordpad or something to generate the file. You should use Notepad or Notepad++ on Windows or similar thing that will create ASCII encoding on Linux. Right now you are using what looks like UTF-8 encoding.
In addition the proper escape sequence for " is \". For instance
line = strtok(data," \"");
Once you fix your file to be in ASCII encoding, you'll find you missed something in your loop.
while(!getfile.eof())
{
//get data and store to variable data
getfile.getline(data,256,'\n');
line = strtok(data," \"");
while(line != NULL)
{
std::cout << line << std::endl;
line = strtok(NULL," \""); // THIS used to be strtok(NULL," ");
}
}//end of while loop
You missed a set of quotes there.
Correcting the file and this mistake yields the proper output.
Have a very careful look at your code:
line = strtok(data," ”");
Notice how the quotes lean at different angles (well mine do, I guess hopefully your font shows the same thing). You have included only the closing double quote in your strtok() call. However, Your data file has:
hello 7 “Mr_Bishop”
which has two different kinds of quotes. Make sure you're using all the right characters, whatever "right" is for your data.
UPDATE: Your data is probably UTF-8 encoded (that's how you got those leaning double quotes in there) and you're using strtok() which is completely unaware of UTF-8 encoding. So it's probably doing the wrong thing, splitting up the multibyte UTF-8 characters, and leaving you with rubbish at the end of the line.

Read File line by line using C++

I am trying to read a file line by line using the code below :
void main()
{
cout << "b";
getGrades("C:\Users\TOUCHMATE\Documents\VS projects\GradeSystem\input.txt");
}
void getGrades(string file){
string buf;
string line;
ifstream in(file);
if (in.fail())
{
cout << "Input file error !!!\n";
return;
}
while(getline(in, line))
{
cout << "read : " << buf << "\n";
}
}
For some reason it keeps returning "input file error!!!". I have tried to full path and relative path (by just using the name of the file as its located in the same folder as the project). what am I doing wrong?
You did not escape the string. Try to change with:
getGrades("C:\\Users\\TOUCHMATE\\Documents\\VS projects\\GradeSystem\\input.txt");
otherwise all the \something are misinterpreted.
As Felice said the '\' is an escape. Thus you need two.
Or you can use the '/' character.
As windows has accepted this as a directory separator for a decade or more now.
getGrades("C:/Users/TOUCHMATE/Documents/VS projects/GradeSystem/input.txt");
This has the advantage that it looks much neater.
first, if you wanna say '\' in a string, you should put '\\', that's the path issue.
then, the string buf is not in connect to your file..
The backslash in C strings is used for escape sequences (e.g. \n is newline, \r carriage return, \t is a tabulation, ...), thus your string is getting garbled because for each backslash+character sequence the compiler is replacing the corresponding escape sequence. To enter backslashes in a C string you have to escape them, using \\:
getGrades("C:\\Users\\TOUCHMATE\\Documents\\VS projects\\GradeSystem\\input.txt");
By the way, it's int main, not void main, and you should return an exit code (usually 0 if everything went fine).

ofstream does not print out newline to txt in Windows7

I have some issue when I want to print out \n I'm using endl for that. And the problem is when I run the code on Windows7 it won't print out the newline. But it will print out newline in Ubuntu. Both OS is using the same compiler GNU g++.
So I wonder if there are some different way to print newline to file in Windows?
void translate(ofstream &out, const string &line, map<string, string> m)
{
stringstream ss(line);
string word;
while(ss >> word)
{
if(m[word].size() == 0)
out << "A";
else
out << m[word] << " ";
}
out << "\n";
}
Outputting either '\n' or using endl will result in the exact same content (the only difference is endl also flushes). When that \n character is written, if the file is in "text mode", the runtime library converts it to the platform's native mechanism to indicate lines. On unix, this is unnecessary because that mechanism is a \n byte. On Windows, that \n becomes \r\n (carriage return, line feed). I suspect you know all of this, but I'm reviewing it just in case.
In short, as long as your runtime library is setup for Windows, the code you have will work as you expect. I suspect you are using cygwin's g++, or some other g++ port, that is not setup for Windows-style lines, even in text mode. Some editors will not correctly interpret that untranslated \n.