954,505 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Problems from string to int array

Hi guys, I've got troubles with a conversion.
My function:
void stringFormat (char *input, int nums)
receives a string like this:
"name;3,45,5,6,77;"
and a number indicating how many numbers in the String (in this case 5)
I've got to tokenize the string in order to obtain:
1) a string named data: "name"
2) an array of int made of the numbers received: numbers[0]=3; numbers[1]=45; and so on 'til 77
Here's my wrong solution:

void stringFormat(char *input, int nums){
	
	char *data;
	int *numbers[nums];
	int i=0;		
	char *p;
	
	p = strtok (input,";");
	if(p != NULL) data=p;
	
	p = strtok (NULL, ",;");
  	while (p != NULL)
  	{
  	  numbers[i] = p;
	  i++; 
	  p = strtok (NULL, ",;");
 	}
	
	i=0;

        /* I check array content  */
	while (i<(nums)){
		printf("%d\n", *(numbers[i]) );
		i++;
	}
}

...any suggestion will be highly appreciated !!

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

>int *numbers[nums];

Doesn't that have to be like... a static value? It may be ok I dunno, If you wanna do that dynamically maybe you need malloc or something? Or you could just initialise it to be a really big value, but that's not cast iron...

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 
Hi guys, I've got troubles with a conversion.
int *numbers[nums];  /* this is an array of pointers of type int */
      
    char *p; /* this is a pointer to a string */
    
     numbers[i] = p; /* You are trying to assign a string to an element of the array of pointers type int */

That doesn't work. You need to convert the number value store in the string pointed by `p' into integer before storing in numbers[i].
Maybe use sscanf() to read the value from the string.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 
>int *numbers[nums]; Doesn't that have to be like... a static value? It may be ok I dunno, If you wanna do that dynamically maybe you need malloc or something? Or you could just initialise it to be a really big value, but that's not cast iron...



Um actually that may be wrong...I could have sworn I remembered something like that not working...lolz

#include <stdio.h>
#include <string.h>
 
void stringFormat ( int nums );
 
int main ( void )
{
  stringFormat ( 143 ); /*test*/
  getchar();
  return 0;
}
void stringFormat ( int nums )
{
  int numbers[nums];
  int i;
  for ( i = 0; i < nums; i++ )
  {
    numbers[i] = 1;
    printf ( "%d", numbers[i] );
  }
}


Anyway, have a look at some daniweb tutorials which you should find useful. http://www.daniweb.com/code/coder5020-timestamp-2.html
http://www.daniweb.com/tutorials/tutorial45806.html

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Um actually that may be wrong...I could have sworn I remembered something like that not working...lolz

#include <stdio.h>
#include <string.h>
 
void stringFormat ( int nums );
 (...)

Your code works correctly on my PC, maybe assigning a variable instead of a static value it's only bad style since I get "only" a gcc warning.
Anyway, even if I iniitialise it with a big value the problem persists.

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 
int *numbers[nums];  /* this is an array of pointers of type int */
      
    char *p; /* this is a pointer to a string */
    
     numbers[i] = p; /* You are trying to assign a string to an element of the array of pointers type int */

That doesn't work. You need to convert the number value store in the string pointed by `p' into integer before storing in numbers[i]. Maybe use sscanf() to read the value from the string.

You guessed the core of the problem.
I've seen some sscanf() tutorials but I've not understood the difference with strtok().
In my case, there's no way to perform a "on the fly" conversion using i.e. atoi()
something like:
numbers[i] = atoi(p);
dunno why it doesn't work!
ps: my variable numbers it's a pointer to an array of int, maybe I missed a couple of parenteses so it looked like an array of pointers of type int..

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

Did you look at those links?

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 
Did you look at those links?


Yes I read something and put the rest in bookmarks, but I've not found my answer.
I'd like to know why my code doesn't work with strtok() and atoi(), before changing everything and using sscanf() (which I found a little tricky..)

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

No idea, I don't have a compiler to test so this is from my head.

It doesn't put it into an array but that's should be trivial. Maybe it will give you hints?

#include <stdio.h>
#include <string.h>
int main ()
{
  char str[] ="retard;3,4510,-5,6,77;";
  char * pch;
  printf ("Splitting: %s",str);
  printf("\n");
  pch = strtok (str,",;");
 
  int count = 0;
  char data[BUFSIZ];
  while (pch != NULL)
  {
     char buf[BUFSIZ];
     char *p;
     printf ("%s ",pch);
 
    int i = strtol(pch, &p, 10);
 
    if (pch[0] != '\n' && (*p == '\n' || *p == '\0'))
    {
      printf (" = Valid integer %d entered\n", i);
      /*Add this to your integer array*/
    }
    else
    {
      printf(" = This is string not an integer\n");
      strcpy(data,pch);
    }
 
     pch = strtok (NULL, ",;");
     count++;  
  }
 
  printf("The string named Data is \"%s\" ",data);
 
  getchar();
  return 0;
}
iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 
You guessed the core of the problem. I've seen some sscanf() tutorials but I've not understood the difference with strtok(). In my case, there's no way to perform a "on the fly" conversion using i.e. atoi() something like: numbers[i] = atoi(p); dunno why it doesn't work! ps: my variable numbers it's a pointer to an array of int, maybe I missed a couple of parenteses so it looked like an array of pointers of type int..


Here's the changes for your code to work using sscanf() to read the integer.

int numbers[nums]; /* this needs to be an array of integers */
    .
    .
    .
     while (p != NULL)
     {
        sscanf(p, "%d", &numbers[i]); /* scan string for an integer */
        ++i; 
        p = strtok (NULL, ",;");
     }
numbers[i] = atoi(p); dunno why it doesn't work!

You need to make numbers[i] an array of integers and not an array of pointers of type int. Right now you are trying to assign whatever atoi(p) gives you to a pointer memory which it can only hold the address of another memory and not an integer value.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

Many thanks! I decided to use strtok() for data and sscanf for numbers, and with some arrangments from the two codes you posted I managed to fix the problem: it seems to work properly.

Unfortunately now I'm discovering that even my string management it's not so good.
I've a problem in recognizing a char array, when I test it with ==.
Let me explain the question with an easy example I've written:

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

int main() {

  char *string;
  char temp[4];

  string = "Bye";

  temp[0]='B';
  temp[1]='y';
  temp[2]='e';
  temp[3]='\0';
    
  compare(string);
  compare(temp);

  return 0;
}



void compare(char* input){

	char *local = "Bye";

	if(local == input) printf("Recognized as equal!\n");
	else printf("Recognized as different!\n");
}


Obviously string is recognized as equal, temp it's not.
At first I thought it was because of the lack of '\0' but in the example I've added it with no results....
I'd like to make temp be recognized as equal to local. Is there some tricks I can usein main without changing the funcion compare() adopting strcmp()?

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

If you want to compare two strings, then you have to use strcmp().

> Obviously string is recognized as equal, temp it's not.
That is more down to accident, rather than design.

A "string" is a constant in many C implementations, which means that the compiler is allowed to take every occurrence of say "bye" and make them all refer to just ONE instance of the string. This potentially saves a lot of space. A side effect of this is that if you try to compare them with just the pointers, they will compare equal (in the same way that &var == &var, for any given variable).

So saying if ( "Bye" == "Bye" ) is really down to whether your compiler chooses to perform string constant merging (or not). If it seems to 'work', then it has nothing to do with the code being correct.-fwritable-strings
Store string constants in the writable data segment and don't uniquize them. This is for compatibility with old programs which assume they can write into string constants.

Writing into string constants is a very bad idea; “constants” should be constant.

This option is deprecated.
gcc4.x removes this option altogether.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

Yes you can't compare strings with == . Use strcmp() as mentioned. Perhaps you might want to peruse this

>Many thanks! I decided to use strtok() for data and sscanf for numbers, and with some arrangments from the two codes you posted I managed to fix the problem

Please can you post your complete solution for the benefit of the community and so others can check over...

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 
Obviously string is recognized as equal, temp it's not. At first I thought it was because of the lack of '\0' but in the example

if(local == input) compares the value of pointer local which is a memory location against the value of pointer input which could be the same memory location or another one.

Maybe this modification to your code throw some light to the matter; take a look at the extra printf() and at the memories addresses in the output :

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

void compare(char* input);

int main() {

  char *string;
  char temp[4];

  string = "Bye";

  temp[0]='B';
  temp[1]='y';
  temp[2]='e';
  temp[3]='\0';
    
  compare(string);
  compare(temp);

  return 0;
}



void compare(char* input){

    char *local = "Bye";

    if(local == input) printf("\nRecognized as equal!\n\n");
    else printf("\nRecognized as different!\n\n");

    /* display what local is pointing to */
    printf ("pointer local says \"%s\"\n", local);

    /* display what input is pointing to */
    printf ("pointer input says \"%s\"\n", input);

    /* display the value these two pointers hold in storage */
    printf ("Memory address value store in pointer `input\' = %p\n", input);
    printf ("Memory address value store in pointer `local\' = %p\n\n", local);

}

/* output:
Recognized as equal!
pointer local says "Bye"
pointer input says "Bye"
Memory address value store in pointer `input' = 00403000
Memory address value store in pointer `local' = 00403000

Recognized as different!
pointer local says "Bye"
pointer input says "Bye"
Memory address value store in pointer `input' = 0022FF70
Memory address value store in pointer `local' = 00403000
*/
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

Many thanks for your indeepth replies, I think I've clearly understood this point, very interesting the example and the link to the faq, it seems it was there just for me!
As requested, I post my final solution to the matter:

void stringFormat(char *input, int nums){
  char *data;
  int numbers[nums];
  int i=0;		
  char *p;
	
  p = strtok (input,";");
  if(p != NULL) data = p;
  
  p = strtok (NULL, ",;");
  while (p != NULL){
	sscanf(p, "%d", numbers[i]);
	i++;
	p = strtok (NULL, ",;");
  }
}

It seems to work properly, but if something is not good style, or can be strengthened, any inputs are obviously welcome!

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

> int numbers[nums];
C89 doesn't allow variable length arrays, this was added to C99.

> sscanf(p, "%d", numbers[i]);
I'm surprised it "worked properly" since you forgot the &
Further, if you want to make sure the user didn't enter "123,abc,456", then you should check the result returned by sscanf().
For extra points, use strtol(), which further enhances error detection by detecting numeric overflow.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 
> int numbers[nums]; C89 doesn't allow variable length arrays, this was added to C99.


Yes, gcc says that, better if I fix it using a constant inside the function? I don't know other ways to solve this issue...> sscanf(p, "%d", numbers[i]);
I'm surprised it "worked properly" since you forgot the &
Further, if you want to make sure the user didn't enter "123,abc,456", then you should check the result returned by sscanf().
For extra points, use strtol(), which further enhances error detection by detecting numeric overflow.
I've not checked the result returned by sscanf() 'cause the string is automatically made by another function where I do error checking.
I forgot the & because my code was slightly different, I used a pointer to an array, and in writing here I forgot it, now it seems I can't edit the code anymore...

BigFormat
Light Poster
45 posts since Sep 2007
Reputation Points: 10
Solved Threads: 0
 

> better if I fix it using a constant inside the function?
Since you're presently scanning the line, then throwing the results away, it might be better to pass a pointer to the int array where you want the results stored.

> now it seems I can't edit the code anymore...
What's that supposed to mean - somebody steal your keyboard?

> I forgot the & because my code was slightly different
If you don't post what you actually tried, then expect long threads and annoyed helpers.
Programming languages do not tolerate vague "well it was something like this". There are many places where being off by just 1 character can radically alter the behaviour of a program. If, in your attempt to approximate the question, you omit this, then anything you get back is meaningless (and a waste of time).

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

>>There are many places where being off by just 1 character can radically alter the behaviour of a program
OMG its sooo true, I've had that happen all too often.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 
> now it seems I can't edit the code anymore... What's that supposed to mean - somebody steal your keyboard?

I think he/she meant due to the time constraint on editting the 'Daniweb posts' they were unable to change their code.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You