Adak 419 Nearly a Posting Virtuoso

You're welcome! ;)

Adak 419 Nearly a Posting Virtuoso

strstr() does exactly what you want, returning a pointer to the first char of the target string it finds. If the target string isn't found, strstr() returns NULL.

Wasn't that easy? ;)

if(strstr(string1, targetString)) {
   //code to handle a target string that was found
}else {
   //code to handle where a target string was not found
}
Adak 419 Nearly a Posting Virtuoso

That's a good program. I can improve it only a small amount.

Here's my question: Once you generate these thousands of primes, you can refer to them over and over again, for your cryptography program - you only have to find the primes just ONCE. So the extreme emphasis on speed is a bit of a mystery.

I thought this might be for a SPOJ or Project Euler problem.

Anyway, I'm still working with it.

Adak 419 Nearly a Posting Virtuoso

I'll test it out, after I get some zzz's. When you print out sizeof(int), what number do you get on your system?

Adak 419 Nearly a Posting Virtuoso

You posted this last week, and I replied with several questions, which you never answered.

1) What code are you using now? There are three different sieve algorithms for primes, which one are you using? Eratotheneis? Please post it.

2) What run times are you hoping for, and what run times are you currently getting?

I have some optimizations for the Sieve of Eratotheneis, but I'll need to run your code on my system, and time it, so I can compare it with mine, and see what optimizations will help.

Adak 419 Nearly a Posting Virtuoso

Quite similar to this:

#include <stdio.h>
#include <string.h>

//struct pair { //  int first,second;//}

void sort(char a[][3], int *, int);
void swap(char a[][3], int *, int, int);

int main(void) {

   int i,n,b[4]={40,30,50,70};
   char a[4][3]={{"pq"},{"aa"},{"km"},{"ls"}};  
   //printf("Enter the number of elements for A");
   n=4; //scanf("%d",&n);
   //printf("Enter %d integers \n ",n);
   //for(i=0;i<n;i++)
     // a[i] = i; // scanf("%d",&arr[i].first);

   //printf("Enter the number of elements of B");
   //scanf("%d",&n);
   //printf("Enter %d integers \n ",n);

   printf("\nBefore sorting\n  a:     b:\n\n");
   for(i=0;i<n;i++)
      printf("%s    %3d\n",a[i],b[i]);   


   sort(a,b,n);    //sort with a as the key
   printf("\nAfter sorting, A is the key:\n  a:     b:\n\n");
   for(i=0;i<n;i++)
      printf("%s    %3d\n",a[i],b[i]);   


   printf("\n");
   return 0;
}


void sort(char a[][3], int *b, int n) {  
   int i,j;
   for(i = 0;i < n-1; i++)
   {
      for(j = i+1;j<n;j++)
      {
         if(strcmp(a[i],a[j])>0)
         {
            swap(a,b,i,j);

         }
      }
   }
}
void swap(char a[][3], int *b, int i, int j) {  
   int temp;
   char ctemp[3];
   strcpy(ctemp,a[i]);
   strcpy(a[i], a[j]);
   strcpy(a[j], ctemp);

   //swap the b array
   temp = b[i];
   b[i] = b[j];
   b[j]= temp;
}
Adak 419 Nearly a Posting Virtuoso

If you just want two arrays sorted, and the data is NOT connected, just remove x2 from sort, and call sort twice. With with sort(a,n), and again with sort(b,n).

If n for a and n for b are not the same size, then you need to use a different variables (easiest), to hold the size of the b array.

Adak 419 Nearly a Posting Virtuoso

This shows your program, with connected array data sorting. If you want to use structs, let me know. The example given for structs is somewhat more complex than necessary.

#include<stdio.h>

//struct pair {
  //  int first,second;
//}

void sort(int *, int *, int);
void swap(int *, int, int);

int main(void) {

   int i,n;
   int a[10],b[10];  
   printf("Enter the number of elements for A");
   n=5; //scanf("%d",&n);
   printf("Enter %d integers \n ",n);
   for(i=0;i<n;i++)
      a[i] = i; // scanf("%d",&arr[i].first);

   //printf("Enter the number of elements of B");
   //scanf("%d",&n);
   printf("Enter %d integers \n ",n);
   for(i=0;i<n;i++)
      b[i]= n-i; //scanf("%d",&arr[i].second);

   printf("\nBefore sorting\n  a:     b:\n\n");
   for(i=0;i<n;i++)
      printf("%3d    %3d\n",a[i],b[i]);   


   sort(a,b,n);    //sort with a as the key
   printf("\nAfter sorting, A is the key:\n  a:     b:\n\n");
   for(i=0;i<n;i++)
      printf("%3d    %3d\n",a[i],b[i]);   


   sort(b,a,n);    //sort with b as the key

   printf("\nAfter sorting, B is the key:\n  a:     b:\n\n");
   for(i=0;i<n;i++)
      printf("%3d    %3d\n",a[i],b[i]);   

   printf("\n");
   return 0;
}


void sort(int *x, int *x2, int n) {  //x could be a[] or b[]
   int i,j;
   for(i = 0;i < n-1; i++)
   {
      for(j = i+1;j<n;j++)
      {
         if(x[i] > x[j])
         {
            swap(x,i,j);
            swap(x2,i,j);
         }
      }
   }
}
void swap(int *c, int i, int j) {  //c could be x or x2 (and x could still be a[] or b[])
   int temp;
   temp = c[i];
   c[i] = c[j];
   c[j]= temp;
}
Adak 419 Nearly a Posting Virtuoso

Insertion sort is VERY fast for small amounts of data, or nearly sorted (or fully sorted!), data.

But this is Substitution sort, and it's almost identical to Bubble sort, but the values being compared, are NOT adjacent. This was my first sort because it was easy to memorize.

@praythius, are you saying that the number DON'T stay associated with the same strings, during the sort? Seems like they should stay connected to each other.

If they DO stay connected, then the ?? is, do you want the string to be the dominant key, or the integers?

Adak 419 Nearly a Posting Virtuoso

Your sort is a substitution sort (very similar to a bubble sort), and your outer for loop should stop at i < n-1, instead of i < n. Because j is i+1, on the last loop.

Adak 419 Nearly a Posting Virtuoso

First thing that I see is line 78 uses x, but x needs to be declared within that function.
Check your syntax with frequent compiles, as you work along. It's hell having done a few hundred lines of code, only to find when you compile them, you have a bucketfull of errors.

Adak 419 Nearly a Posting Virtuoso

That won't do, doesn't meet specs. Get a cup of coffee or splash some water on your face, or soemthing. You need to get firing on all cylinders here!

Product ID and price, are both integers, with a tab between them, in the data file.

FILE *fp;
fp = fopen("products.txt", "rt");

if(!fp) {
   printf("Error! File not opened\n");
   return 0;
}


//when done reading the file
fclose(fp);

fp is short for file pointer, but the name can be whatever you like, as long as it's not a keyword in C.

You should work through a few C tutorials. Many are available on the net. One of them is here, (click on the C Tutorial tab)
http://cboard.cprogramming.com/c-programming/

Adak 419 Nearly a Posting Virtuoso

Have you created the products.txt file yet, with the necessary spec's as you describe here?

  1. The product IDs and product prices are stored in a table format in a file named
    products.txt. Create a text file in the same folder as your .c file and type in two columns
    (ID and price) separated by a tab. product ID and price are integers

You can't read a file's data correctly, until you have the file. As I understand it, you will manually type this data into the file, and keep it. I would make a backup copy, just in case - you don't want to have to enter it again if it gets scrambled by your program.

You'll need a FILE *pointer, (of course, *) as use an fopen() to open the file in read mode. Then fscanf() should be all you need, since the data is in a strict format, which will not change.

Give that a try.

Adak 419 Nearly a Posting Virtuoso

First, Welcome to the forum, lp94!

You need to start your program, and then ask for help, on specific problems. We weren't in your class, and this is YOUR assignment.

Think of it as though you had no computer. How would you start this with just paper and pen? Give it a good try and post up your result. Without this requirement, we'd be doing every students homework 24/7. I know you understand.

Adak 419 Nearly a Posting Virtuoso

Most common problem in C - the hidden newline when dealing with a char

Add one space in scanf(" %c", etc.), and all will be well. The space in the format string, tells scanf() to go past any whitespace, including a newline.

Adak 419 Nearly a Posting Virtuoso

That is a LOT of primes! ;)

You were using the simple "test by mod" for a remainder, before?

Before I suggest something, give me:

1) info about your time requirements. Is there a time limit of some kind?

2) info about the system that is running this program. What cpu and compiler will be running this program.

When you print("%d",sizeof(int)), what do you get?

Because there are several algorithms for this, and each of them favors certain searches for primes, over others.

I'm guessing (just a guess), that the Sieve of Eratotheneis is a good choice, but we'll see.

Adak 419 Nearly a Posting Virtuoso

Perhaps you are using the angle of 45 you have defined, instead of calculating the real angle on the bounce off the bricks, or the wall.

If you Google for that equation, you'll find it easily. I don't have it on this system, but it's simple geometry.

Adak 419 Nearly a Posting Virtuoso

Your character should have struct members which define all his attributes in any given area. If not, the area should have that info, so your player has everything he's earned, wherever he goes (some of it may not be functional in some area's, but he still has it).

Adak 419 Nearly a Posting Virtuoso

Sourceforge has a lot of projects, but I like the puzzle type problems myself. Try ProjectEuler, SPOJ, etc.

Some of those problems are REAL "projects".

Adak 419 Nearly a Posting Virtuoso

You googled for "node deletion in binary trees in C", and received NO hits?

Without code, I have no idea of why your logic isn't working.

Adak 419 Nearly a Posting Virtuoso

A "void" is an empty area - like "space is mostly a huge void". It also means "amounting to nothing" as in "the lawsuit was made null and void".

So a void function is any function that returns nothing. It may say "return" at the end of it, but it will have no value after the word "return", and the use of the "return" word is strongly discouraged.

Adak 419 Nearly a Posting Virtuoso

You can use strstr() (searches for a string, inside a string), to search each line of the file, as it's read.

That will hugely simplify your program. Work with code based around logic similar to this:

char *pstr=NULL; 
char line[80];
char target[12]; //plenty of room is good
FILE *fp;
//open the file, and get the string you want to search for, into target[].
//get one line from the file
while((fgets(line, sizeof(line), fp)) != NULL) { // to get each line of the file.
   pstr=strstr(line, target);
   if(pstr) {
      printf("Found it: %s \n",line);
   }
}

C is NOT C++, and you'd be wise to use one or the other. Learning two languages half-way, is not great, and mixing them is a disaster, before long.

Adak 419 Nearly a Posting Virtuoso

Columnar printing becomes more difficult, because all monitors print up in row order. That means you have to use more than just basic print commands for output.

I haven't seen a program to help with this, but there may be one available. What are you trying to print and what is the width of the columns?

The easy way to do this is to use a large char array to represent your "page", and then rearrange the data in the array, so it's in the column ready format, you want.

For example, you keyboard:
Now is the time for all good men to come to the aid of their country, which when rearranged, becomes:

Now is the
time for all
good men to
come to the
aid of their
country.

Adak 419 Nearly a Posting Virtuoso

Make your printf() format, occupy 80/number of columns you want to have including spaces between columns.

If I want 4 columns, I have my printf() format use 20 spaces, etc.

#include <stdio.h>

int main(void) {
   int n;

   for(n=0;n<200;n++) {
      printf(" %18d ",n);  //4 columns, each one 18+2 wide.
   }
   printf("\n");
   return 0;
}
Adak 419 Nearly a Posting Virtuoso

The nested two for loops are usually the easiest way to make designs with rows and columns. You just need to see the pattern that is used, to make the design you want.

Use the outer for loop for the row control, and the inner for loop to control the chars being printed in the current row.

You need to add logic to both the inner, and the outer for loop, for this to work. Be careful that row logic goes in the outer for loop, and column logic goes in the inner for loop, only.

That's a good exercise for you to work with!

Adak 419 Nearly a Posting Virtuoso

What is "arrayList", and why are you copying Letters + 2? IMO, you should be using strcpy(), instead of strncpy(), since the words will have different lengths.

Adak 419 Nearly a Posting Virtuoso

Yeah, probably could. But I won't, because it's a challenge, and just giving the answer removes all the challenge. No challenge, no fun!

If that problem is too difficult, why not start with easier one's, and work your way up? A lot of figuring out how to code up answers to these programming challenges, is to practice - it's a bit like swimming - you will never swim well, without getting into the water, and practicing your swimming.

Even the great Sherlock Holmes, was always learning things as he went from case to case, solving crimes.

Adak 419 Nearly a Posting Virtuoso

Look at the second example: you need two numbers from his "favorites", whose sum is divisible by 9.

So it's a problem of reading in the data, and juggling the favorite numbers in each case, to find the highest numbers, that are divisible by 9 when added together. Since reading in the data is a fixed amount of time, generally, it's the "juggling" of the favorite numbers that is the heart of the matter.

I was surprised to see that so many of the attempts turned in, had wrong answers. ;(

Kind of a shame this is such an uninteresting problem. Any light bulbs go off?

Adak 419 Nearly a Posting Virtuoso

D'question, I do not d'C. ;)

Adak 419 Nearly a Posting Virtuoso

To be honest, this problem doesn't seem interesting to me. I did see that only 22% of the submissions, were good on this problem - so it's relatively low on successes.

What I like to do with a puzzle/problem is first, work through it by hand (perhaps with a simplified example of the problem first. After doing it with paper and pencil, a time or 3, I notice ways and then better ways, to solve it.

That makes the backbone of my initial coding effort's logic.

Since checking for a sum of nine among the numbers sounds efficient, perhaps that check, beginning with the largest numbers, would be a good place to start.

If you need the greatest numbers (of some kind), you still want to center your logic, around those largest numbers, for your search, imo.

If you were given a list of numbers, how would YOU find the greatest N of those numbers, whose sum adds up to 9, efficiently?

Adak 419 Nearly a Posting Virtuoso

Because in the search for an answer, your algorithm should always favor the larger numbers, in the search for the password. Smaller numbers get lower priority.

http://en.wikipedia.org/wiki/Greedy_algorithm

Adak 419 Nearly a Posting Virtuoso

There is an excellent PDF document on Quicksort, freely available. I got it from Googling for Quicksort.

The choice of a pivot in Quicksort is crucial. Best choice I have found in many tests, is using (left + right)/2. It's faster than median of three, and gives better sub-array distribution than choosing it randomly.

At best, Quicksort is 0(n log n), which is the best any comparison sorter can be. A poor choice of a pivot can change that quite a bit, however.

The best improvement you can make to Quicksort, is to use Insertion Sort, on the sub-array's, once they are down to a small size. Insertion sort SCREAMS if it has a small amount of data to be sorted, and the data is already partially sorted! The improvement is about 15%, so it's VERY noticeable.

The "small size" for an i7 Intel cpu system, is between 17 and 100, in my tests. Below 17, you don't get the full benefit of using Insertion Sort, and above 100, the benefit of using Insertion Sort, begin to fade.

//for a recursive version of Quicksort, just add this to to the top of the Quicksort function:

if(right - left < 50) {
   InsertionSort(array, left, right);
   return;
}

Quicksort is the fastest (general purpose) sorter, and the "horrid" data scenario so frequently mentioned for Quicksort, has never happened to me. The choice of (left+right)/2 for the pivot, and using Insertion Sort too, has undoubtedly helped that out.

Since it uses …

Adak 419 Nearly a Posting Virtuoso

In C, ALL parameters are passed by copying - NOTHING ELSE. When you copy an address (pointer), you have a way of affecting the original variables that are pointed to by the address - so it's a pass by reference, in it's effect.

You pass a 2D array to a function, by just using the name of the array, in the call to the function:

myfunction(arrayName);

In your function parameter list a 2D int array like this:

void myFunction(int arrayName[][NumberOfColumns]) {
   //other code in here


}

Note that the number of rows (in the first [], is not needed. All other dimensions size, need to be included, however.
NO *'s are needed, at all, which seems to be the confusing factor.

Arrays in C are ALWAYS passed by the address (which is the name of the array most commonly). The receiving function has to have the greater share of explicit info about the array, if it is to be treated as an array - instead of just as a "something" at a certain address. (which is also possible, but not recommended - especially for beginners). In this latter type, you are working explicitly with pointers (addresses) and offsets, which makes it not as easy to understand.

Adak 419 Nearly a Posting Virtuoso

We would hope that you will tell us what is the problem with the program - then we can focus on a specific spot within your program, to look for errors.

Saves a lot of time, that way, and gives you a chance to develop some better problem solving skills of your own - debugging your program is a skill set that you need to practice to be any good at it.

ALWAYS use code tags around your C code, so it retains it's C indentations! Those are SO important to show the logic in the code, instead of just html (forum) text formatting - which makes code look like something the cat threw up yesterday. :(

Just highlight your code, and click on "Code" in the header of the edit window - done!

I really like the overall design of this program - it's wonderfully compact. Just hard to read through as C code, when it's formatted this way.

Can you repost it and use the code tags, and tell us what the problem is that we should focus on?

Thanks, and welcome to the forum! ;)

zeroliken commented: nicely said +9
Adak 419 Nearly a Posting Virtuoso

A better solution is to count up how many values you're putting into your array. For instance, what if the lowest value was zero? What if you have no idea what the lowest value might be in the data?

The better logic is:

1) count the number of values you are putting into your array, and loop ONLY through those values. 30 Values read in? Then you'll search from array[0] to array[29], only.

2) set the initial minimum value to the first value you put into your array. If the value is 100, and there are lesser values in the data, that's OK. Because you'll have an if() statement inside the loop:

if(newValue is < minimumValue)
   minimumValue = newValue;

and you have the minimum value as soon as you've read in all the newValues, and made this comparison.

It's fast, (no dealing with irrelevant array values (lots of zeroes), clear, and accurate.

Adak 419 Nearly a Posting Virtuoso

isalpha() tests only ONE char - not a whole string. You'll need to loop through the entire string with either a pointer, or an array index, to test each value in the string, one at a time.

Adak 419 Nearly a Posting Virtuoso

String compare (strcmp()), compares strings, not a string and a char.

Remember what a string is - a group of contiguous char's, with a terminating NULL char (generally written as '\0', but sometimes just as a 0 (zero).

So '+' can't work - it's just one char. "+" could work, because it's the string literal char + which the compiler has placed a terminating null char, right behind it (which you can't see, and that is the source of a lot of confusion).

Adak 419 Nearly a Posting Virtuoso

If 2^60th is less than your maximum unsigned long long int, then you can display it the exact same way you display any other unsigned long long int. Use printf's format display flags.

If it's larger than any integral data type, then you need to either print it out as a string of digits (type char array[]), or array of int's (type int array[]), but before you can do that, you need to translate a binary number into a decimal number.

You didn't read the Wikipedia page I suggested yet, did you? Tut tut, old boy! ;) If you intend to do some programming, you have to show some initiative, what?

Adak 419 Nearly a Posting Virtuoso

Why not add a print statement with two getchar()'s afterward (to pause the screen) the first time through the loop, and print out exam[0] and correct[0] and see what's going on?

It looks right, but sometimes the errors are just too simple to catch with a look through.

Are you compiling or running this program in Debug mode? If so, try a release mode. Sometimes debug mode gets twisted 'round.

Adak 419 Nearly a Posting Virtuoso

Yes, only one semi-colon on that line of code! Thanks, Rubberman.

Adak 419 Nearly a Posting Virtuoso

I believe you might be immensely helped by taking your simple code:

char* str[] = {"thank","you","adak"};
char** s[] = {str+1, str+2, str+3};

/* now change "adak" to "Alex", right HERE
   and print Alex, instead of adak
*/


printf("%s",**(s+2));

;) Now tell me what you think!

Adak 419 Nearly a Posting Virtuoso

Well, I wasn't sure when I first read your initial post, but now, I'm pretty sure. See if this example doesn't stir up some zing for you:

I want to find 2^2. (It is frequently best to tackle a big thing, by first studying a smaller example of it).

2^2 = 4, and what is 4 in binary? 000 001 00 (spaces for emphasis only).

Note the 1 is followed by two zero's. And this is for 2 to the second power.

2 zeroes, and two the the 2nd power. 2 and 2, see how they match up?

Let's test it: 2^5 = 2*2*2*2*2 = 32 and 32 in binary is 001 00000 (spaces for emphasis).

So 2^2 is 1 followed by two 0's, in the byte and 2^5 is 1 followed by 5 0's in the byte.

So what is 2^10 and 2^20, and 2^60, in binary? Righto: 1 followed by 10 zeroes, 1 followed by 20 zeroes and 1 followed by 60 zeroes.

Now there are two ways I see to finish this:

1) If 2^60 is smaller than an unsigned long long int on your system, then you can handle it directly

if not:
2) you have to translate the binary number you have, into decimal

So there you are. I can't do any more without just doing it for you. Read Wikipedia on binary numbers, and if you're still stuck, refer to Google "binary numbers to decimal numbers", and read up.

Adak 419 Nearly a Posting Virtuoso

First off, I'm not sure, OK?

For smaller numbers, I'd suggest looking into bit shifting, and how each shift leftward, multiplies by 2. Bit shifting is among the fastest operations on a computer, in C.

00000001 = 1
00000010 = 2
00000100 = 4
etc.

But your number far exceeds the capacity of any integral data type in C, so:

Plan B: <light bulb!> ;)

The key point, the final number [in binary], can be calculated directly because the base of the number is 2, and the computer represents numbers in base 2. That means NO multiplication of shifting, is necessary, whatsoever.) print the final number, as a string of digits, from the calculation.

00001000 = 8,

etc.

Convert the binary to a string of single digits, and print them. Don't try to represent 2^60, unless you see in limits.h that it's within the range of an integral data type on your system (perhaps unsigned long long?).

Adak 419 Nearly a Posting Virtuoso

Hi, I get the error "warning: array ‘str’ assumed to have one element [enabled by default]" when I am trying to fill in values inside the string array.

#include<stdio.h>

int main(void) {
   //unless there's a good reason (like to use global memory), variables are local
   //here only, the compiler will count the number of strings I need, for me
   char *str[]; {"hello","my","name","is","tubby"}; 
   int i = 0;

    for(i=0; i<5; i++)
       printf("%s\n",str[i]);

    return 0;
}

That's how I'd write it.

Adak 419 Nearly a Posting Virtuoso

You shouldn't code like that.

Be specific in what you want the compiler to reserve for space.

In fact, if you create an array, and it has almost no space, you can "get away" with overrunning it, by several char's, or pointers to char's, even integers. Usually about 7, but it depends on the compiler, and system.

C does not guarantee that a program with inadequate space will crash - it may run, if you're lucky. Extend this program out to 20 strings, and I'm thinking it's a crasher - but again, I don't code like this, and I've tested it only a few times, with integers.

No, you shouldn't be casting the return from malloc, but most importantly, you should be making your space, adequate and explicit. IMO, this:

char str[n][m] is a true two dimensional array
char *str[n] is an array of pointers to chars, which is very similar to a true 2D array, but not the exact same thing.

Work it clockwise:

str -> [] string is an array
[] -> * of pointers
* - > circles around to the end of the line, then continues on around still going clockwise around str, to find

char

In a spiraling clockwise loop.

Adak 419 Nearly a Posting Virtuoso

No! >.<

Show what you have tried. :D

Adak 419 Nearly a Posting Virtuoso

It used to be necessary, but that has been deprecated for a long time now. You should NOT cast the return from malloc (which is a void pointer), because it is automatically right for every data type.

There are cases where the data type is not a basic type in C, when a cast becomes necessary, but it is rarely the case.

Adak 419 Nearly a Posting Virtuoso

Break it down:

1) you'll need to have a loop to generate the fibonacci sequences, and

2) you'll need to have logic to save the bit pattern of the number the user input, before your program enters the loop mentioned above.

Once you get that working, the rest is entirely trivial. Give that a try.

Adak 419 Nearly a Posting Virtuoso

As a beginner in C, you DEFINITELY want to use an array of chars for the words:
words[NumberOfWords][40].

Where NumberOfWords could be just a few hundred or 40,000 or more. There are very few English words that are longer than 39 letters, (save 1 space for the end of string char), outside of scientific nomenclature.

You'll want to declare this array above main(), to get global memory (heap), not try to use the smaller stack inside a function, for it.

Word lists are available on the net, btw. A single word can then be referenced with
words, in a loop, like:


int i=0;
while((fscanf(YourFilePointer, "%s", words[i]))>0)
   ++i;
Adak 419 Nearly a Posting Virtuoso

Personally, I'd use fgets() to get the whole line of text from the process file:
fgets(charBufferName, sizeof(charBufferName), filePointerName);

which easily gets 1 line of data, and in a while loop, gets every line of data:

int i=0;
while((fgets(buffer, sizeof(buffer), fpName)) != NULL) {
   //then use sscanf() to get the data into your arrays:
   sscanf(buffer, "%s %s %s ", array1[i],array2[i],array3[i]);
   ++i;
}

strtok() is fine, but you always have to watch out for what you can't see - that it changes the string it's tokenizing.