Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Split string into substrings

Split string into substrings

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++performancequestion
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Manfr3d
    wrote on last edited by
    #1

    Hello guys, I want to split a string into substrings using strtok(). The code is

    #include "stdafx.h"

    #using #include #include #include using namespace System;
    using namespace std;

    char str2list(char* str, char** list, const char* delimiters)
    {
    for (char c = 0; c < sizeof(list) / sizeof(char*); c++)
    {
    list[c] = strtok(str, delimiters);
    if (list[c] == NULL) break;
    }
    return c;
    }

    int _tmain()
    {
    char** arglist;
    arglist = new char*[16];
    char* exmp = "I have a problem!";
    str2list(exmp, arglist, " ");
    for (char c = 0; c < sizeof(arglist) / sizeof(char*); c++)
    {
    cout << arglist[c] << endl;
    }
    delete[] arglist;
    return 0;
    }

    When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator. Does anyone have an idea why this doesn't work? Thanks and best wishes.

    S 1 Reply Last reply
    0
    • M Manfr3d

      Hello guys, I want to split a string into substrings using strtok(). The code is

      #include "stdafx.h"

      #using #include #include #include using namespace System;
      using namespace std;

      char str2list(char* str, char** list, const char* delimiters)
      {
      for (char c = 0; c < sizeof(list) / sizeof(char*); c++)
      {
      list[c] = strtok(str, delimiters);
      if (list[c] == NULL) break;
      }
      return c;
      }

      int _tmain()
      {
      char** arglist;
      arglist = new char*[16];
      char* exmp = "I have a problem!";
      str2list(exmp, arglist, " ");
      for (char c = 0; c < sizeof(arglist) / sizeof(char*); c++)
      {
      cout << arglist[c] << endl;
      }
      delete[] arglist;
      return 0;
      }

      When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator. Does anyone have an idea why this doesn't work? Thanks and best wishes.

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #2

      Austrian_Programmer wrote:

      When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator.

      That's because (although exmp is a char*), it's pointing at a string stored in read-only memory (string literals are read-only). strtok needs to write to it. It can't, so you get a runtime exception. Change

      char\* exmp = "I have a problem!";
      

      to

      char exmp\[\] = "I have a problem!";
      

      and the crash goes away, because now you've allocated a read/write character array and initialised it from the (read-only) string literal. There are many other issues as well, however:

      1. Look at the strtok documentation[^] - you only pass in str on the first call to strtok for that string - the rest of the time, you pass in NULL.
      2. The loop condition in str2list is all wrong. list is a char**, so sizeof(list)/sizeof(char*) will be equal to 1. If you want to be safe with respect to the size of list, you need to explicitly pass it in - C/C++ doesn't pass around array sizes with arrays.
      3. Similarly, the loop condition in _tmain is wrong (although this problem goes away if you take note of the next point).
      4. There's no point using new when you have a fixed array size - declaring arglist with char* arglist[16]; will work just as well.
      5. I'm...interested that you use char as the type of the loop variables
      6. Although the for loop in str2list may compile with the compiler you're using, it won't with VS2008 (and possibly won't with earlier compilers), and isn't compliant with the C++ standard - going by the standard, your loop variable isn't accessible outside the loop.
      7. You return the number of tokens in the list from str2list...and then don't use it. Mmmmm.

      Anyway - here's my fixed (I think) version of your code.

      #include <iostream>
      #include <string.h>

      using namespace std;

      int str2list

      M 1 Reply Last reply
      0
      • S Stuart Dootson

        Austrian_Programmer wrote:

        When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator.

        That's because (although exmp is a char*), it's pointing at a string stored in read-only memory (string literals are read-only). strtok needs to write to it. It can't, so you get a runtime exception. Change

        char\* exmp = "I have a problem!";
        

        to

        char exmp\[\] = "I have a problem!";
        

        and the crash goes away, because now you've allocated a read/write character array and initialised it from the (read-only) string literal. There are many other issues as well, however:

        1. Look at the strtok documentation[^] - you only pass in str on the first call to strtok for that string - the rest of the time, you pass in NULL.
        2. The loop condition in str2list is all wrong. list is a char**, so sizeof(list)/sizeof(char*) will be equal to 1. If you want to be safe with respect to the size of list, you need to explicitly pass it in - C/C++ doesn't pass around array sizes with arrays.
        3. Similarly, the loop condition in _tmain is wrong (although this problem goes away if you take note of the next point).
        4. There's no point using new when you have a fixed array size - declaring arglist with char* arglist[16]; will work just as well.
        5. I'm...interested that you use char as the type of the loop variables
        6. Although the for loop in str2list may compile with the compiler you're using, it won't with VS2008 (and possibly won't with earlier compilers), and isn't compliant with the C++ standard - going by the standard, your loop variable isn't accessible outside the loop.
        7. You return the number of tokens in the list from str2list...and then don't use it. Mmmmm.

        Anyway - here's my fixed (I think) version of your code.

        #include <iostream>
        #include <string.h>

        using namespace std;

        int str2list

        M Offline
        M Offline
        Manfr3d
        wrote on last edited by
        #3

        Thanks for the answer. I've done a lot of microprocessor programming in the last time and there I use char whenever possible (it's the smallest type and working without causing any troubles). However, that's pure C and there are (I know) a few differences to C++. Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.

        S 1 Reply Last reply
        0
        • M Manfr3d

          Thanks for the answer. I've done a lot of microprocessor programming in the last time and there I use char whenever possible (it's the smallest type and working without causing any troubles). However, that's pure C and there are (I know) a few differences to C++. Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #4

          Austrian_Programmer wrote:

          Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.

          That's cool - if you're starting out with C++ on a desktop platform, I really would recommend learning about the Standard Template Library - it makes (some) things a lot easier, especially managing strings and arrays (or vectors, which is the closest thing to an array in STL)..

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups