Hey i have a weird problem when im trying to print out elements in my temp pointer array, at the bottom where im just using cout to print random indexs of temp, it will only work if i comment out temp[1]... anyone have any idea why? if its not commented out, it doesnt print anything, even from the other couts

int main(){
	ifstream ins;
	ins.open("Line.txt", ios::in);

	char *temp[7];
	char line[100];

	while(!ins.eof() && ins.good())
	{
		int i = 0;
		
		ins >> line;
		cout << line << endl;
		
		temp[i] = strtok(line, ":");
		while(temp[i] != NULL)
		{
			i++;
			temp[i] = strtok(NULL, ":");

		}
		cout << temp[0] << endl;
		//cout << temp[1] << endl;
		cout << temp[5] << endl;
		cout << temp[4] << endl;
	}
}

my lines.txt file just has random stuff like
erge:hguir:ieowrj:wre:tg:erf:qwer:
htr:hty:wer:Reg:rht:wef:trg:
34:trgh:wer:234:er:rg:234:

Recommended Answers

All 5 Replies

You kids and your string toking!

Firstly, if your filename is actually "lines.txt" (as you say at the bottom of your post) then that's probably the filename you should use in your program. :)

And you should test the stream like this: while (ins >> line)

Sorry if this sounds harsh, but there are numerous problems with your code's logic. Is it guarranteed that there are a max of 7 tokens in your strings? And that the size of those is 99 chars max? And that all of the lines in your file don't contain whitespace? (istream << reads until the whitespace! ;) )

A bit more foolproof version of the program would look like this for instance:

int main(){
	ifstream ins;
	ins.open("Line.txt", ios::in);

	char *temp[7];
	char line[100];

	while(!ins.eof() && ins.good())
	{
		
		ins >> line;
		cout << line << endl;
		
		temp[0] = strtok(line, ":");
		for(int i = 1; temp[i] != NULL && i < 7; i++)
		{
			i++;
			temp[i] = strtok(NULL, ":");

		}
		cout << temp[0] << endl;
		//cout << temp[1] << endl;
		cout << temp[5] << endl;
		cout << temp[4] << endl;
	}
}

Here's the correct version of your program to my best knowledge.

#include <iostream>
#include <fstream>
using namespace std;

static const unsigned int maxWords = 50;
static const unsigned int maxLineLen = 500;


int main() {
    ifstream ins;
    ins.open("Line.txt", ios::in);

    char *temp[maxWords];
    char line[maxLineLen];

    //while (!(eof || fail || bad))
    while (ins.good()) {
        //fetch a new part til newline
        ins.getline(line, maxLineLen);
        //show it
        cout << line << endl;

        //set the first word
        temp[0] = strtok(line, ":");

        //fill the elements, maximum of the array's size.
        for (unsigned int i = 1; i < maxWords; i++) {
            temp[i] = strtok(NULL, ":");
            //can't put this in for-condition, i gets incremented BEFORE condition check
            if(temp[i] == NULL) break;
        }

        //find until there are no more words, or no more elements for the words
        for (unsigned int i = 0; temp[i] != NULL && i < maxWords; i++) {
            cout << temp[i] << endl;
        }
    }

    return 0;
}

Clockowl: Your program will still fail if a line is too long since only part of the line will have been read, leaving the rest of that line to be read as the next line. It's probably best to forgo strtok altogether and just use C++ strings and member functions like find_first_of and substr. (Also note that the version presented below definitely needs the colon at the end of the line, as in the OP's original data file.)

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

int main() {
    ifstream ins ("Line.txt");
    string line;
    vector<string> fields;

    while (getline (ins, line)) {
        cout << line << '\n';

        size_t lastPos = 0;
        while (true) {
            size_t pos = line.find_first_of (":", lastPos);
            if (pos == -1) break;
            fields.push_back (line.substr (lastPos, pos - lastPos));
            lastPos = pos + 1;
        }

        for (int i = 0; i < fields.size(); ++i)
            cout << fields[i] << '\n';
        fields.clear();
    }
}

Nucleon: You didn't return anything from main and compared -1 and and unsigned int (size_t). Also, the code creates lots of strings with zero length, which is probably not wanted.

But yeah, C++ classes and functions are way better for this than C types and functions.

Anyway, here's the code the OP can hand in to his teacher (we didn't really answer his question though. xD)

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

int main() {
    ifstream ins ("Line.txt");
    string line;
    vector<string> fields;

    while (getline (ins, line)) {
        cout << line << '\n';

        int pos, lastPos = 0;
        while ((pos = line.find_first_of(":", lastPos)) != -1) {
            if((pos - lastPos) > 0)
                fields.push_back (line.substr (lastPos, pos - lastPos));
            lastPos = pos + 1;
        }

        for (int i = 0; i < fields.size(); ++i)
            cout << fields[i] << '\n';
        fields.clear();
    }

    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.