473,513 Members | 2,554 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strtok question

10 New Member
If I understand it correctly, strtok scans from the first character after the separator. The code below:
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. void main()
  6. {
  7.     char *rules[50];
  8.     int priority[50];
  9.     int i=0;
  10.     char line[100]=" (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)(frule, 3)(grule, 20), (srule, 100)";
  11.  
  12.     char *tok = strtok(line,"(");
  13.     rules[i]=strtok(NULL,",");
  14.  
  15.     tok=strtok(NULL,")");
  16.     priority[i]=atoi(tok);
  17.     i++;
  18.  
  19.     while((tok=strtok(NULL,"("))!=NULL)
  20.     {
  21.         rules[i]=strtok(NULL,",");
  22.         tok=strtok(NULL,")");
  23.         priority[i]=atoi(tok);
  24.         i++;
  25.     }
  26.  
  27.     for(int j=0;j<i;j++)
  28.     {
  29.         cout<<rules[j]<<endl;
  30.         cout<<priority[j]<<endl;
  31.     }
  32. }
gives an output like this:

arule
12
brule
21
zrule
70
drule
25
erule
10

However, if I remove the space between " and (arule, 12) so the line would look like:

Expand|Select|Wrap|Line Numbers
  1.     char line[100]="(arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)(frule, 3)(grule, 20), (srule, 100)"; //there's no space between " and (arule, 12)
then the output would become:

brule
21
zrule
70
drule
25
erule
10

Why is a space needed between " and the first separator in order for the program to work correctly? Am I doing something incorrectly?
Mar 23 '07 #1
8 2128
horace1
1,510 Recognized Expert Top Contributor
the first token is framed with (, so try
Expand|Select|Wrap|Line Numbers
  1.     char line[100]="(arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)(frule, 3)(grule, 20), (srule, 100)";
  2.     char *tok; 
  3.     rules[i]=strtok(line,"(,");
  4.  
Mar 23 '07 #2
cting76
10 New Member
the first token is framed with (, so try
Expand|Select|Wrap|Line Numbers
  1.     char line[100]="(arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)(frule, 3)(grule, 20), (srule, 100)";
  2.     char *tok; 
  3.     rules[i]=strtok(line,"(,");
  4.  
Thank you. That fixes the problem.

I then modified the input into:

Expand|Select|Wrap|Line Numbers
  1. char line[100]="(arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)(frule, 3)(grule, 20), (srule, 100)";
Notice that there's no "," between "(erule, 10)", "(frule, 3)", and "(grule, 20)". What I want to do is, let the program read from "(arule, 12)" until "(erule,10)", pause right before "(frule,3)", do something, then continue reading "(frule, 3)", pause before "(grule, 20)", do something, then continue reading "(grule,20), (srule, 100)".

So far I've tried adding:

Expand|Select|Wrap|Line Numbers
  1. char next[2]=")";
and then changing the while loop to:

Expand|Select|Wrap|Line Numbers
  1.     while((num=strtok(NULL,"("))!= NULL && (num=strtok(NULL,"("))!=next)
  2.     {
  3.         rules[i]=strtok(NULL,",");
  4.         num=strtok(NULL,")");
  5.         priority[i]=atoi(num);
  6.         i++;
  7.     }
but the output becomes:

arule
12
zrule
70
erule
10
srule
100

I figured everytime a strtok is called it changes the beginning token so I then changed the while loop into:

Expand|Select|Wrap|Line Numbers
  1.     while((num=strtok(NULL,"("))!= NULL)
  2.     {
  3.         rules[i]=strtok(NULL,",");
  4.         num=strtok(NULL,")");
  5.         priority[i]=atoi(num);
  6.         i++;
  7.  
  8.         if(num==next)
  9.             cout<<"pause"; //to test if the condition works
  10.     }
but the output becomes:
arule
12
brule
21
zrule
70
drule
25
erule
10
grule
20
srule
100

What am I doing wrong?

Thank you.
Mar 24 '07 #3
cting76
10 New Member
Will someone be so kind to point out why my program hangs? It doesn't give out any error message other than "<program_name has stopped working>".

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. void main()
  6. {
  7.     ifstream infile;
  8.     char c[256],str[64];
  9.     char *rules[50];
  10.     int priority[50];
  11.     int i=0;
  12.     char *num;
  13.  
  14.     cout<<"Enter the name of input file: ";
  15.     cin.get(str, 64);
  16.  
  17.     infile.open(str);
  18.  
  19.     for(i=0;i<256;i++)
  20.     {
  21.         c[i]=infile.get();
  22.         cout<<c[i];
  23.     }
  24.  
  25.     cout<<endl;
  26.     i=0;
  27.  
  28.     rules[i]=strtok(c,"(,");
  29.     num=strtok(NULL,")");
  30.     priority[i]=atoi(num);
  31.  
  32.     cout<<endl;
  33.     cout<<rules[i];
  34.     cout<<endl;
  35.     cout<<priority[i];
  36.     cout<<endl;
  37.  
  38.     i++;
  39.  
  40.     while((num=strtok(NULL,"("))!=NULL)
  41.     {
  42.         rules[i]=strtok(NULL,",");
  43.         cout<<rules[i]<<endl;
  44.         num=strtok(NULL,")");
  45.         priority[i]=atoi(num);
  46.         cout<<priority[i]<<endl;
  47.         i++;
  48.     }
  49. infile.close();
  50. }
The input file has only one line:
(R10, 10), (R20, 20), (R90, 90), (R75, 75), (R35, 35), (R60, 60).

The program works just fine if I include the input line in the program (in other words: char c[100]="(R10, 10), (R20, 20), (R90, 90), (R75, 75), (R35, 35), (R60, 60)"; works just fine). But it would hang at the while loop when the input is reading from a file. It would output

R10
10
R20
20
R90
90
R75
75
R35
35
R60
60

but hangs right after 60. Looks to me it is unable to "satisfy" the !=NULL condition but I can't why.

Any advice appreciated.

Thank you.
Mar 25 '07 #4
horace1
1,510 Recognized Expert Top Contributor
your program works fine with GNU C++.
The problem may be in your the loop where you read a line from the file
Expand|Select|Wrap|Line Numbers
  1.     for(i=0;i<256;i++)
  2.     {
  3.         c[i]=infile.get();
  4.         cout<<c[i];
  5.     }
  6.  
in that the string is not being properly null terminated with your compiler.
try
Expand|Select|Wrap|Line Numbers
  1.     infile.get(c,256);
  2.  
so you read up to 256 characters or until a newline is found
Mar 25 '07 #5
cting76
10 New Member
Expand|Select|Wrap|Line Numbers
  1. infile.get(c,256);
  2.  
so you read up to 256 characters or until a newline is found
Thank you! I wasn't aware of the difference between c[i]=infile.get() and infile.get(c,256). Now the program can read the line just fine. However, it hangs again if the input is like this:

(arule, 10), (brule,20)(crule, 30)(drule, 40), (erule, 50)(frule, 60)

I use Visual Studio and it simply says the program (the one I wrote) has stopped working. The output would look like this:

arule
10
brule
20
drule
40
erule
50

(crule, 30) and (frule, 60) are both missing. I think it's got something to do with how the delimiter is set up. What I am trying to do is, let the program read block "(arule, 10), (brule, 20)", do something, read (crule, 30), do something, read block "(drule, 40), (erule, 50)", do something, then read (frule, 60) and do something. So how do I make a condition that says if current token ends with ")" and there's a "(" immediately follows, then do something before continue reading next block?

Thank you.
Mar 25 '07 #6
horace1
1,510 Recognized Expert Top Contributor
it gives a segmentation error with Visual; C++ on my machine
the problem is if strtok() returns NULL within your loop - you need to check and if so exit the loop, e.g.
Expand|Select|Wrap|Line Numbers
  1.     while((num=strtok(NULL,"("))!=NULL)
  2.     {
  3.         if((rules[i]=strtok(NULL,","))==NULL)break;
  4.         cout<<rules[i]<<endl;
  5.         if((num=strtok(NULL,")"))==NULL)break;
  6.         cout << "num " << num <<endl;
  7.         priority[i]=atoi(num);
  8.         cout<<priority[i]<<endl;
  9.         i++;
  10.     }
  11.  
Mar 25 '07 #7
cting76
10 New Member
it gives a segmentation error with Visual; C++ on my machine
the problem is if strtok() returns NULL within your loop - you need to check and if so exit the loop, e.g.
Expand|Select|Wrap|Line Numbers
  1.     while((num=strtok(NULL,"("))!=NULL)
  2.     {
  3.         if((rules[i]=strtok(NULL,","))==NULL)break;
  4.         cout<<rules[i]<<endl;
  5.         if((num=strtok(NULL,")"))==NULL)break;
  6.         cout << "num " << num <<endl;
  7.         priority[i]=atoi(num);
  8.         cout<<priority[i]<<endl;
  9.         i++;
  10.     }
  11.  
Shouldn't num=strtok(NULL,"(")) return NULL if there's no more element after the last ")"?
Mar 25 '07 #8
cting76
10 New Member
Alright I have modified my code into this:

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. using namespace std;
  5.  
  6. #define index 5
  7.  
  8. struct am{
  9.     string rule;
  10.     int priority;
  11. }set[index];
  12.  
  13. void printset(am amg)
  14. {
  15.     cout<<amg.rule<<endl;
  16.     cout<<amg.priority<<endl;
  17. }
  18.  
  19. void main()
  20. {
  21.     ifstream infile;
  22.     char c[256],str[32];
  23.     char *rules[50];
  24.     int priority[50];
  25.     int i=0;
  26.     char *num;
  27.  
  28.     cout<<"Enter the name of input file: ";
  29.     cin.get(str, 32);
  30.  
  31.     infile.open(str);
  32.     infile.get(c,256);
  33.  
  34.     set[i].rule=strtok(c,"(,");
  35.  
  36.     for(i=0;i<index;i++)
  37.     {
  38.         num=strtok(NULL,")");
  39.         set[i].priority=atoi(num);
  40.         num=strtok(NULL,"(");
  41.         set[i+1].rule=strtok(NULL,",");
  42.     }
  43.     for(int n=0;n<index;n++)
  44.         printset(set[n]);
  45.  
  46. infile.close();
  47. }
That solves the while loop problem. But another problem still stands: the program reads just fine with input of (arule, 10), (brule,20), (crule, 30), (drule, 40), (erule, 50), (frule, 60). But if the input is (arule, 10), (brule,20)(crule, 30)(drule, 40), (erule, 50)(frule, 60), the program will hang.

Please advise on how to tell the strtok to separate ") from "(", or pause at ")" if the immediate element is "(". Thank you.
Mar 25 '07 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

5
8734
by: tvn007 | last post by:
// I am using strtok to break the string // For example: to extract 5 from the string below: // TEST 1,P,5,PASS // Below is my code in C: ptr =strtok(testbuff," \t\n,()"); ptr =strtok(NULL," \t\n,()"); ptr =strtok(NULL," \t\n,()"); ptr =strtok(NULL," \t\n,()");
7
5693
by: Fernando Barsoba | last post by:
Hi, I'm using strtok() in the following way: void obtain_param(char *pmsg, CONF_PARAMS *cnf ) { char *s1, *s2; size_t msg_len; s1 = strtok (pmsg,":"); if (s1) {
13
4900
by: ern | last post by:
I'm using strtok( ) to capture lines of input. After I call "splitCommand", I call strtok( ) again to get the next line. Strtok( ) returns NULL (but there is more in the file...). That didn't happen before 'splitCommands' entered the picture. The problem is in splitCommands( ) somehow modifying the pointer, but I HAVE to call that...
17
5176
by: bofh1234 | last post by:
I need to delimit a string. The delimiters are a semicolon and comma. When I run the program I get a segmentation fault on the first strtok. I followed the examples of others and from my old C books, but I can't seem to find the problem. The accesslist has a format of 20,45;22,44;46,28;99,43,etc. What am I doing wrong? Thanks, #include...
8
1915
by: hu | last post by:
hi, everybody! I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0. Program is simple, but mistake is confusing. First, the below code can get right outcome:"ello world, hello dreams." #include <stdafx.h> #include <string.h> #include <stdio.h> int main()
5
25791
by: Kelly B | last post by:
I need a function which returns me a "word" from a given string and then sets the pointer to the next one which is then retrieved during further calls to the function. I think strtok( ) is the solution but i could not understand the use of the function as given in the C99 standard EXAMPLE #include <string.h> static char str =...
11
904
by: Lothar Behrens | last post by:
Hi, I have selected strtok to be used in my string replacement function. But I lost the last token, if there is one. This string would be replaced select "name", "vorname", "userid", "passwort" from "users" order by "users"
3
4660
by: krista | last post by:
Hi, I am beginner of C++. When I try to read a file and put it into X and Y variables. I got that segmentation fault. the data file is data.txt: 4.4 6.8 3.2 -5.5 3.3 0.9
8
309
by: Stu Cazzo | last post by:
Hi all, I have a question on why strtok is doing what it's doing for my splitString( string2 ); call. Below is the output for the entire program: token was: word1 token was: word2 token was: word3 token was: word1
0
7270
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7178
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7397
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7543
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5704
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3255
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3242
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
817
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
473
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.