Detecting the end of line in a text file

Pages: 12
Nov 3, 2018 at 12:31am
closed account (21R4z8AR)
I need to read 4 variables from a text file but sometimes the line could have less than 4 values to read from. I need to be able to detect if a line has ended and produce an error message and skip to the next line in the file.
This is some of the bits from the code that I'm looking at. Sorry I'm new to all this I don't know the terminology.

for (int i = 0; i <= numLines; i++)
{
inputFile >> firstValue;

if (inputFile.peek() == '\n')
{
cerr << "ERROR: First value only, ignoring line of the input file";
continue;
}

I thought checking for a '\n' would work but apparently the text files that I'm using done have any '\n', so I'm at a complete loss.
Nov 3, 2018 at 12:41am
closed account (21R4z8AR)
The input text files look like this:

44

100 90 usable BothMatch

110 120 broken NoMatch

183

170 140 usable BothMatch
Nov 3, 2018 at 1:38am
1
2
3
4
5
6
7
8
9
10
11
12
string line;
while(getline(input, line)){
   stringstream ss(line);
   ss >> a >> b >> c >> d;
   if(not ss){
      //wrong data type or wrong number of parameters
   }
   if(not ss.eof()){
      //remaining characters
      // (¿may you have whitespace at the end? remove them with ss >> std::ws; )
   }
}


> I thought checking for a '\n' would work but apparently the text files that I'm using done have any '\n', so I'm at a complete loss.
¿could it be a windows/linux/mac format issue?
Nov 4, 2018 at 11:26pm
closed account (21R4z8AR)
What is the ss supposed to be?
Nov 4, 2018 at 11:44pm
Just a name of a variable of type stringstream. Read up on stringstream. Makes working with files easier
Last edited on Nov 4, 2018 at 11:44pm
Nov 5, 2018 at 12:53am
closed account (21R4z8AR)
Is there any way to check if its the wrong data type and produce an error message for that and separately check if its the wrong number of parameters, AND do it it for each variable in between a b c and d
Nov 5, 2018 at 12:54am
Yes. Just read each variable separately and test after each one.
Nov 5, 2018 at 1:02am
closed account (21R4z8AR)
Why is this so difficult lol, when I try the

int a
ss >> a
if (!ss)
{
cerr << "not an integer";
}

The !ss always results in true even when in the file it is an integer.
Nov 5, 2018 at 1:09am
An example (accepting lines of 1 integer or 3 integers):

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
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

void proc1(int a) {
    cout << a << '\n';
}

void proc3(int a, int b, int c) {
    cout << a << ',' << b << ',' << c <<'\n';
}

int main() {
    string line;
    while (getline(cin, line)) {
        istringstream sin(line);
        int a, b, c;
        if (!(sin >> a)) {
            if (sin.eof())
                cout << "missing a\n";
            else
                cout << "bad a\n";
        }
        else if (!(sin >> b)) {
            if (!sin.eof())
                cout << "bad b\n";
            else
                proc1(a);
        }
        else if (!(sin >> c)) {
            if (sin.eof())
                cout << "missing c\n";
            else
                cout << "bad c\n";
        }
        else {
            if (!(sin >> ws).eof())
                cout << "extra crap\n";
            else
                proc3(a, b, c);
        }
    }
}

Last edited on Nov 5, 2018 at 2:02am
Nov 5, 2018 at 1:16am
closed account (21R4z8AR)
That would be perfect if I could get 'sin >> a' to work properly
Nov 5, 2018 at 1:24am
I have no idea what the problem could be. You've shown some unformatted code with missing semicolons, but I really don't know what to make of it. You need to paste a complete, runnable program for me to see what's actually going on. Preferably in code tags, if you can manage it.

Anyway, surely my example works for you?
Nov 5, 2018 at 1:50am
closed account (21R4z8AR)
Okay nevermind as far as im aware right now it all works. A couple more questions
1. idk what I did but cout is "ambiguous" now. What could I have possibly changed?
2. Is there anyway to make an error message if there was extra data in the line?
Nov 5, 2018 at 1:53am
closed account (21R4z8AR)
never mind lol now its not ambiguous, but I still have my second question.
Nov 5, 2018 at 1:54am
The "extra crap" branch is where it ends up if it detects non-whitespace after the final integer.
Nov 5, 2018 at 1:57am
closed account (21R4z8AR)
Ah I see thank you so much for the help :)
Nov 5, 2018 at 2:02am
closed account (21R4z8AR)
does eof inside the getline loop work like "end of line"?
Nov 5, 2018 at 2:03am
Yes, in the context of a stringstream, eof means "end of line" (i.e., no more data to read from the input, so really the same thing).

Note that I've simplified that test a little bit. It says "if you don't detect eof (after skipping any whitespace from the current position), then there's extra crap on the line".
Last edited on Nov 5, 2018 at 2:06am
Nov 5, 2018 at 2:31am
closed account (21R4z8AR)
AHH nevermind its not working still :(
Could there be a problem that the data is coming from a file not cin?
Also the last two variables are strings in my code :/
Nov 5, 2018 at 2:55am
You would obviously need to show me a runnable example of the problem. How else could I possibly help? The devil's in the details.

But of course it needs to be changed for your strings. I assume you've done that. It's not just going to magically work trying to read strings as ints.
Last edited on Nov 5, 2018 at 2:56am
Nov 5, 2018 at 2:55am
closed account (21R4z8AR)
So I broke down the general gist of my program to this and it works so I guess im just missing something in my main program, Ill have to figure it out :(

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <iomanip>
#include <fstream>
#include <math.h>
#include <string>
#include <sstream>

using namespace std;

int main()
{
	ifstream inputFile;
	char inputName[1024] = { '\0' };
	string c = "c";
	string d = "d";
	int a = 0;
	int b = 0;
	string line;
	istringstream sin;

	cin >> inputName;
	inputFile.open(inputName);

	while (getline(inputFile, line))
	{
		istringstream sin(line);

		if (!(sin >> a))
		{
			if (sin.eof())
			{
				cerr << "\nError no more data";
				break;
			}
			else
			{
				cerr << "\nincorrect datatype";
			}
		}

		else if (!(sin >> b))
		{
			if (sin.eof())
			{
				cerr << "\na value only";
				continue;
			}
			else
			{
				cerr << "\nincorrect data type";
			}
		}
		else if (!(sin >> c))
		{
			cerr << "\na and b value only";
			continue;
		}
		else if (c != "x" && c != "y")
		{
			cerr << "\nC value isnt correct";
			continue;
		}

		else if (!(sin >> d))
		{
			cerr << "\na and b and c value only";
			continue;
		}
		else if (d != "x" && d != "y")
		{
			cerr << "\nd value isnt correct";
			continue;
		}
		else if (!(sin >> ws).eof())
		{
			cerr << "\nignorning extra data";
			continue;
		}
	}
	return 0;
}
Pages: 12