0

The following function works on text file called "_filePath" and tries to cut it to little tokens separate by ";" and "," like this:

[Mickey M;12034;911416313;M;01a;9001;NULL;0;13;12;0;CPP,C;MSC,3D;FEND,BEND,SEC;]

When trying to separate CPP,C into little token, it doesn't reach the next token which is MSC,3D and so on. I notice that the function doesn't even reach the block beginning with if (tokNum==1).

I really need HELP, thank you very much :D

void File::set() {

    if (_filePath.is_open()) {
        while (_filePath.getline(line, 250)) {
            char *token; char *tokeng;
            int tokNum = 0;
            token = strtok(line, ";");
            while (token != NULL) {
                index = 0;
                if (token == "NULL") token = NULL;  

                if (inputType == EMP){
                    if (tokNum == 0){
                        int numWord = seprateElements(token);
                        empKnoledge = new string[numWord];
                        tokeng = strtok(token, ",");
                        while(tokeng != NULL) {
                            empKnoledge[index] = tokeng;
                            index++;
                            tokeng = strtok(NULL, ",");
                        }
                    }

                    if (tokNum == 1){
                        int numWord = seprateElements(token);
                        empAfeild = new string[numWord];
                        tokeng = strtok(token, ",");
                        while(tokeng != NULL) {
                            empAfeild[index] = tokeng;
                            index++;
                            tokeng = strtok(NULL, ",");
                        }
                    }
                    if (tokNum == 2){
                        int numWord = seprateElements(token);
                        empPfeild = new string[numWord];
                        tokeng = strtok(token, ",");
                        while (tokeng != NULL) {
                            empPfeild[index] = tokeng;
                            index++;
                            tokeng = strtok(NULL, ",");
                        }
                    }
                }

                tokNum++;
                token = strtok(NULL, ";");
            }

            numLine++;
        }
    }
    getchar();
}

int seprateElements(char *line) {   // check size of elements in line by counting ','
    int count = 0;
    while (*line++ != '\0') {
        if (*line == ',')   count++;
    }
    return count+1;
}
grebulon
  • 7,697
  • 5
  • 42
  • 66
Noa
  • 25
  • 1
  • 6
  • Have you tried debugging it? – Richard Critten Jun 03 '15 at 11:20
  • 1
    lol `strtok`... this is 2015! – Lightness Races in Orbit Jun 03 '15 at 11:20
  • Voted to close (we are not a debugger). That said, consider rewriting your code to do these steps: first, split the input into tokens; second, process tokens separately, as needed (apparently the first three tokens require special processing). See [here](http://stackoverflow.com/a/236803/186997). Also, consider not using: `new`, `strtok`, raw `char*`s, and `getchar`. They are bad practice/non-standard/unsafe for C++. – utnapistim Jun 03 '15 at 11:24
  • What is `inputType`? I can only see it *used* in your code, not defined. What is the smallest code sample that shows your problem (and no smaller - or bigger). – doctorlove Jun 03 '15 at 12:19
  • oh.. i forgot to say that the inputType is an enum – Noa Jun 03 '15 at 13:01

2 Answers2

2

In C++ there is nice classes and functions, such as std::string, std::istringstream and std::getline.

The first, std::string is the class you should use for strings. The second class, std::istringstream, is an input stream that works on strings instead of files. Finally, the std::getline function can be used to get a line from a stream into a std::string object, but it has an optional argument that allows it to separate fields on a special character, for example the semicolon.

Using these functions you could to something like

std::string line;
while (std::getline(_filePath, line))
{
    // Put the line into an input string stream
    std::istrimgstream linestream(line);

    std::string name;
    std::string id;
    // ... all other fields in the line
    std::string last_field;  // or whatever you want to name it

    // Now extract all the fields from the line
    std::getline(linestream, name, ';');
    std::getline(linestream, id, ';');
    // ... all other fields
    std::getline(linestream, last_field);  // Last field, no separator needed

    // Some fields contains multiple tokens separated by comma
    // Example extracts token from the last field of the line
    std::istringstream tokenstream(last_field);
    std::string token;
    while (std::getline(tokenstream, token, ','))
    {
        std::cout << "Extracted token '" << token << "'\n";
    }
}

On an unrelated side-note, please try to avoid your own symbols with leading underscore, in many cases they are reserved.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    You should mention performance implications of this approach; while they might be irrelevant and in 99% cases it is a good tradeoff - they certainly do exist (number of extra allocations your code will be doing, is huge, and allocation is still damn expensive). – No-Bugs Hare Jun 03 '15 at 11:54
0

Use String token Split , see following code do for you.

#include<iostream>
#include<string.h>
using namespace std;

int main()
{
   char str[]="Mickey M;12034;911416313;M;01a;9001;NULL;0;13;12;0;CPP,C;MSC,3D;FEND,BEND,SEC;";
   char *pch = strtok (str,";,");
  while (pch != NULL)
  {
    cout<<pch<<"\n";
    pch = strtok (NULL, ";,");
  }
   return 0;
}
Venkata Naidu M
  • 351
  • 1
  • 6