Read last line text file

Pages: 12
Aug 16, 2013 at 1:06am
Guys need some help,
I am making a script to read the latest from a text file. the script already does this but I'm kind of lost to adjust some things

He picks up the line by numbytes in fseek, but the data line may vary and numbytes not be accurate, how can I fix this?

And another problem is that the line has, date, time, value, separated by space, how to read that line and put these 3 information in variable?

#include <stdio.h>
#include <conio.h>

int main()
{
FILE *arq;
char Line[100];
char *result;
int tam, i;
// Opens a file for READING TEXT
arq = fopen("temp.txt", "rt");
if (arq == NULL) // If there was an error in opening
{
printf("Problems opening file\n");
return 2;
}
// Read last line text file
tam= -25;
fseek(arq, tam, SEEK_END);
i = 1;
while (!feof(arq))
{
result = fgets(Line, 100, arq);
if (result) // If it was possible to read the report online content
printf("%d : %s",i,Line);
i++;
}
fclose(arq);
}
Aug 16, 2013 at 4:28am
Please use code tags. The <> button...
I would use fstream.
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
34
35
36
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
        char * data1,data2,data3;
	fstream file; // If you don't know what std::fstream is, look it up
	file.open("temp.txt");
	if(!file.is_open())
	{
		cout << "Problem opening file.\n";
		return 2;
	}
	file.seekg(EOF); // go to the end of file
	while(true)
	{
		file.unget(); //go back two chars
		file.unget();
		char in = file.get();
		if(in == '\n')
		{
                        //get line from file until space is encountered and put it in data1
			file.getline(data1,' ');
                        file.getline(data2,' '); //etc
                        file.getline(data3,' ');//etc
			break;
		}
	}
        //send the data to the output stream
	cout << "Data: " << data1 << " " << data2 << " " << data3 << endl; 
        //end program
	return 0;
       
}


I pretty much typed this up in my browser, not guarranteed to work, but pretty sure it does. Hope this helps!

-SDude
Aug 16, 2013 at 5:46am
Superdude wrote:
I pretty much typed this up in my browser, not guarranteed to work, but pretty sure it does. Hope this helps!

Just glancing at it, I can guarantee it won't work.


Here's something that will.
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
#include <iostream>
#include <fstream>
#include <string>

std::string getLastLine(std::ifstream& in)
{
    std::string line;
    while (in >> std::ws && std::getline(in, line)) // skip empty lines
        ;

    return line;
}

int main()
{
    std::ifstream file("temp.txt");

    if (file)
    {
        std::string line = getLastLine(file);
        std::cout << line << '\n';
    }
    else
        std::cout << "Unable to open file.\n";
}


or, a tiny bit more efficient:
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
34
35
36
37
38
39
#include <iostream>
#include <fstream>
#include <limits>
#include <string>

std::istream& ignoreline(std::ifstream& in, std::ifstream::pos_type& pos)
{
    pos = in.tellg();
    return in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::string getLastLine(std::ifstream& in)
{
    std::ifstream::pos_type pos = in.tellg();

    std::ifstream::pos_type lastPos;
    while (in >> std::ws && ignoreline(in, lastPos))
        pos = lastPos;

    in.clear();
    in.seekg(pos);

    std::string line;
    std::getline(in, line);
    return line;
}

int main()
{
    std::ifstream file("temp.txt");

    if (file)
    {
        std::string line = getLastLine(file);
        std::cout << line << '\n';
    }
    else
        std::cout << "Unable to open file.\n";
}
Last edited on Aug 16, 2013 at 5:47am
Aug 16, 2013 at 1:42pm
Superdude and cire thank you for help

The code below worked fine, good even, but I need one more help

The "line" returns 3 values​​, date, time and value, how can I get these 3 values ​​and put in 3 variables?

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
34
35
36
37
38
39
#include <iostream>
#include <fstream>
#include <limits>
#include <string>

std::istream& ignoreline(std::ifstream& in, std::ifstream::pos_type& pos)
{
    pos = in.tellg();
    return in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::string getLastLine(std::ifstream& in)
{
    std::ifstream::pos_type pos = in.tellg();

    std::ifstream::pos_type lastPos;
    while (in >> std::ws && ignoreline(in, lastPos))
        pos = lastPos;

    in.clear();
    in.seekg(pos);

    std::string line;
    std::getline(in, line);
    return line;
}

int main()
{
    std::ifstream file("temp.txt");

    if (file)
    {
        std::string line = getLastLine(file);
        std::cout << line << '\n';
    }
    else
        std::cout << "Unable to open file.\n";
}
Aug 16, 2013 at 4:08pm
Thanks cire for the correction.
This (should) work for splitting the data into three vars.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string vars[3];
int whichVar = 0;
for(unsigned int i = 0; i < line.size(); i++)
{
        if(!line[i] == ' ')
        {
               vars[whichVar] += line[i]; //add the non-space char to the current
//variable        }
        else
        {
               whichVar++; //switch the variable being used
        }

}


This will only work as long as there are no spaces besides the separating ones. This will work if there is only two data members as well. or five, six, or seven, just change the size of the array.

Cire, if this is wrong too, please correct. ;)
Aug 16, 2013 at 5:09pm
Superdude believe have put this in the correct part of your code, fix the lack of "}" but n...
Aug 17, 2013 at 2:25am
Could you elaborate?
Aug 17, 2013 at 8:30am
a better way for doing the splitting:
1
2
3
4
5
6
7
std::string::size_type tmp;
std::vector<std::string> values;
for (std::string::size_type tmp=i=0; i!=std::string::npos; tmp=i)
{
    i=line.find(' ',tmp);
    values.push_back(std::string(tmp,i-tmp);
}
Last edited on Aug 17, 2013 at 8:30am
Aug 18, 2013 at 1:34pm
Superdude not understand how the code would look with your mod or the theranga
Aug 18, 2013 at 2:48pm
1
2
std::istringstream input( the_last_line );
input>>date>>time>>value;
Aug 18, 2013 at 5:06pm
1
2
std::istringstream input( the_last_line );
input>>date>>time>>value;


ne555
tested not working well

example the last line:
"17/7/2013 12:37:20 19,625"

script return using your suggestion
"17
0
1.32657e-315"
Aug 18, 2013 at 6:03pm
ne555
tested not working well

example the last line:
"17/7/2013 12:37:20 19,625"

script return using your suggestion
"17
0
1.32657e-315"
Report


Date and time are not numbers. Why are you attempting to extract them as if they are?


1
2
std::string date, time, value ;
input >> date >> time >> value ;
Last edited on Aug 18, 2013 at 6:04pm
Aug 18, 2013 at 10:09pm
for me at least I think I got a better way to split the data, however I am having trouble splitting time and value, I do not think one way of defining reliable, can you help me?

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
#include <limits>
#include <string>
#include <sstream>
#include <stdlib.h>

std::istream& ignoreline(std::ifstream& in, std::ifstream::pos_type& pos)
{
    pos = in.tellg();
    return in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::string getLastLine(std::ifstream& in)
{
    std::ifstream::pos_type pos = in.tellg();

    std::ifstream::pos_type lastPos;
    while (in >> std::ws && ignoreline(in, lastPos))
        pos = lastPos;

    in.clear();
    in.seekg(pos);

    std::string line;
    std::getline(in, line);
    return line;
}

int main()
{
    std::string var1;
    std::string var2;
    std::string var3;
    std::ifstream file("temp.txt");

    if (file)
    {
        std::string line = getLastLine(file);
        
 	std::istringstream iss(line);
        getline(iss, var1, ' ');
        std::cout << var1 << '\n';
        getline(iss, var2, ' ');
        std::cout << var2 << '\n';
        getline(iss, var3, ' ');
        std::cout << var3 << '\n';
    }
    else
        std::cout << "Error\n";
        return 2;
}


example the last line:
"17/7/2013 12:37:20 19,625"

script return
17/7/2013
12:37:20 19,625

Aug 19, 2013 at 7:16pm
Any solution?
Aug 19, 2013 at 9:15pm
in the text file, you could put a ':' or other char to separate the two. Then on the input, check for that char.
Aug 19, 2013 at 9:54pm
He would have troubles with the time.
He already has whitespaces to separate them, so he should use whitespaces for that.
Aug 21, 2013 at 4:35pm
I managed to finish, grace your help, thanks to all who contributed.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
#include <limits>
#include <string>
#include <sstream>
#include <stdlib.h>

std::istream& ignoreline(std::ifstream& in, std::ifstream::pos_type& pos)
{
    pos = in.tellg();
    return in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::string getLastLine(std::ifstream& in)
{
    std::ifstream::pos_type pos = in.tellg();

    std::ifstream::pos_type lastPos;
    while (in >> std::ws && ignoreline(in, lastPos))
        pos = lastPos;

    in.clear();
    in.seekg(pos);

    std::string line;
    std::getline(in, line);
    return line;
}

int main()
{
    std::string var1;
    std::string var2;
    std::string var3;
    std::ifstream file("temp.txt");

    if (file)
    {
        std::string line = getLastLine(file);
        
 	std::istringstream iss(line);
        getline(iss, var1, ' ');
        std::cout << var1 << '\n';
        getline(iss, var2, '\t');
        std::cout << var2 << '\n';
        getline(iss, var3);
        std::cout << var3 << '\n';
    }
    else
        std::cout << "Error\n";
        return 2;
}
Aug 21, 2013 at 4:48pm
1
2
3
    else
        std::cout << "Error\n";
        return 2;


Are you aware that this will cause the app to exit with a status code of 2, regardless of whether the condition on line 37 is true or false?
Aug 21, 2013 at 5:45pm
to fix some of this, thanks

leveraging would like to see one more question,

I am trying to convert the string to double using:
"var4 = Convert.ToDouble (var3);"

But I get the error

[Error] 'Convert' was not declared in this scope
Aug 21, 2013 at 6:00pm
Well? Is it declared anywhere in your code?
Pages: 12