Read and then write strings.

Ladies and Gents,

I have an assignment right now where I must read a text file "mail.dat. While reading this text file I must located and write only strings with the @ symbol. I am looking for just email addresses within the text. My end goal is to just export strings located within the lines with the @ symbol and add these to a separate text file named "list.dat"

Below is an example of how far I have gotten and I have been scratching my head trying to figure out just how to output a simple line to the other file. I am new so give me your worst.
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
29
30
31
32
33
  #include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main ()
{
	string line;
	ifstream indata;
	ofstream outdata;



	indata.open("e:mail.dat");
	outdata.open("e:list.dat");

	if (! indata)
		cout<< "The file mail.dat cannot be opened" <<endl;

	if (! outdata) 
		cout<< "The file list.dat cannot be opened"<<endl;

	while (indata.eof())

		getline (indata,line);
	cout << <<endl;




	return 0;
}
First of all, are you sure that colons are allowed in file names? (They're not in Windows; not sure about other OSs.)
(If you meant to open E:\mail.dat, use indata.open("E:\\mail.dat");.)

To read a file line by line, do
1
2
3
4
5
6
while (getline(indata, line))
{
    // Do stuff with 'line'
    // For instance, this will output 'line' straight to the other file
    outdata << line << '\n';
}
I am using VS C++ express 2010 and the files seems to open fine as I can get output from the first one. I have made adjustments to my code but I cannot for the life of me understand why length.line() is flagged with an error I have also tried size.line() and it fails.


#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main ()
{
int pos;
int lenstring;
string line;
string email;
ifstream indata;
ofstream outdata;

{

indata.open("G:\\mail.dat");
outdata.open("G:\\list.dat");

if (! indata)
cout<< "The file mail.dat cannot be opened" <<endl;

if (! outdata)
cout<< "The file list.dat cannot be opened"<<endl;

while (indata.eof())
indata>>line; // read the string
lenstring = length.line();// find the length of the sring
pos =line.find("@"); // determine the position of the string that contains "@"

if (pos<=lenstring && pos>)

cout<< "The file Mail.dat contains the following e-mail address"<< endl;

outdata << line;




cout<< "The file Mail.dat contains the following e-mail address"<< endl;
You want line.size() rather than length.line(). Also, it is unnecessary, just test against std::string::npos:
1
2
3
4
5
6
7
8
9
10
11
...
std::cout << "The file Mail.dat contains the following e-mail addresses:\n";

while (std::getline(indata, line)) {
    size_t pos = line.find('@');
    if (pos != std::string::npos) {
        outdata << line;
        std::cout << " - " << line << "\n";
    }
}
...


EDIT: Oops, wrote 'a' instead of '@'
Last edited on
Thanks for helping me out ,but the code you suggested is above my head. I need to use a very basic algorithm to find the emails as this is for a class project.

I would also like to understand how my code would extract just the strings that contain the "@" sign if I do not test against the pos.

also, shouldn't the line below output just the emails that we found or would i have to created another variable line email after I use the if pos?

outdata << line ; // output string only string that contain "@"

input data into my other file?

Sorry guys but I have read my chapters multiple time and I even bought another book hoping I could get this broken down Barney style somewhere.
I am not entirely sure what you are asking. I'll just break down my code for you:

1) I am looping the while loop over getline. This is because getline returns true if it succeeds in getting data from the file, and false otherwise. This is better then looping on EOF because sometimes it means that it will fail reading, even though it hasn't reached EOF yet.

2) I am searching the line that was received for the '@' symbol. find returns the position in the string that contains the '@' symbol, or std::string::npos otherwise. std::string::npos is simply a constant defining the biggest possible number returned by the function.

3) If the result isn't std::string::npos, I know that '@' must be in the string somewhere. Therefore, I can print the string to the output because it must be an email.


Note that here, pos was unnecessary, but I kept it there for readability. If you prefer, you could change lines 5 and 6 to:
if (line.find('@') != std::string::npos) {
I apologize for the misunderstanding. What I am trying to accomplish is simply reading text lines from a text file "mail.dat" for strings that contain an "@". The program is then supposed to output only the strings that contain "@" into another file. I am just trying to get it to output the strings to the console for now that contain the "@" (which should be email addresses) first to make sure it works then I will work on the output to the file myself. The problem I am having is that I cannot get the data to display anything and I was getting the errors I mentioned in my first post. Thanks for any input I am a lowly newb.
new code is below:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main ()
{
int pos;
int lens1;
string s1;
string email;
ifstream indata;
ofstream outdata;



indata.open("G:\\mail.dat");
outdata.open("G:\\list.dat");

if (! indata)
cout<< "The file mail.dat cannot be opened" <<endl;

if (! outdata)
cout<< "The file list.dat cannot be opened"<<endl;

if (indata.is_open())


{
while (! indata.eof())// read the entire file including white space till the end of the file

indata >> s1;


pos= s1.find("@"); // find the "@" in the string

lens1 = s1.size(); // find the size of the string

if (pos<= lens1 && pos>lens1) // if the "@" character is within the measured sting than cout as s1


cout<< "The file Mail.dat contains the following e-mail address"<< endl;
cout << s1 << endl;
outdata << s1;
}

{

indata.close();
outdata.close();

}


return 0;
}
it is only reading the first sting though.
Topic archived. No new replies allowed.