LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-05-2006, 07:16 AM   #1
linuxlover1
Member
 
Registered: Jun 2003
Location: UK
Posts: 54

Rep: Reputation: 15
Help with C pointers


Hello... i've started to learning C and i have a litle problem.
Lets say that i want to create an array to holds strings
eg. "January","February","March"
In C i have to create an array with pointers on it that point to another array each.. eg.
-----------------------------------------------------------------------
#include <stdio.h>
int main() {
char *array[4]; // the array i want
int i;
for (i=0;i<=3;++i) //Reading the data to the array
scanf("%s",array[i]); //eg.January
for (i=0;i<=3;++i)
printf("%s\n",array[i]) //printing the Data
//eg. January
// February
// March
return(0);

}
-----------------------------------------------------------------------
In the above code sth is going wrong. The results are not correct like the program doesn't shows the months correctly.
This has to do with the reading or with the printing ?
I'm i using the pointers the wrong way ??
please help. Thx A Lot !
 
Old 07-05-2006, 07:30 AM   #2
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
That would be better (although still quite weak):
Code:
char array[4][16];
 
Old 07-05-2006, 07:33 AM   #3
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
The pointers of your array point to random memory locations, and you have not reserved memory to store the strings.

This is more or less the simplest variation of your progrram that does work:
Code:
#include <stdio.h>
#define MAXLINE 100

int main() {
    char array[4][MAXLINE + 1];
    int i;
    for (i=0;i<=3;++i) 
	   fgets(array[i], MAXLINE, stdin);
    for (i=0;i<=3;++i)
	   printf("%s",array[i]);
    return(0);
}
 
Old 07-05-2006, 07:33 AM   #4
leonscape
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Debian SID / KDE 3.5
Posts: 2,313

Rep: Reputation: 48
Your createing an array of pointers, but the pointers themselves are not set to anything.

The scanf function is trying to place information into the address that the pointers point to, it does not change the pointers to point at a new c string. try using this as the array statement.

char array[4][80];
 
Old 07-05-2006, 10:15 AM   #5
linuxlover1
Member
 
Registered: Jun 2003
Location: UK
Posts: 54

Original Poster
Rep: Reputation: 15
Thx a lot men !!

i just wander , is there any way to do it using an array of pointers instead of a 2D array ??
If there isn't one that means that this code:
<< char *array[]={"ONE","TWO","THREE"}; >>
works only that way, i mean that i must store my strings to the array as above and then to access the array like "array[i]"
I can't load the array data at run time with scanf("%s",array[i]).
 
Old 07-05-2006, 10:36 AM   #6
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by linuxlover1
i just wander , is there any way to do it using an array of pointers instead of a 2D array ??
Sure but you will need to initialise the pointer and ensure that the pointer points to sufficient memory. Take a look at the malloc() and free() functions.

<snip> sorry had a typo in malloc()<end snip>

Last edited by graemef; 07-05-2006 at 12:22 PM.
 
Old 07-05-2006, 12:01 PM   #7
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
POOR (doesn't allocate memory for strings, will probably crash):
Code:
#include <stdio.h>
int
main (int argc, char *argv[])
{
  /* BAD: We're only allocating pointers, not the strings 
          being pointed to! */
char *array[4];
  int i;

  /* Reading the data to the array */
  for (i=0; i<=3; i++)
  {
    scanf("%s", array[i]);
  }

  /* printing the Data (eg. January, February, March, ...) */
  for (i=0; i<=3; i++)
  {
    printf("%s\n",array[i]);
  }

  /* Done */
  return 0;
}
BETTER: (allocates a fixed # of fixed-length strings):
Code:
#include <stdio.h>
#include <strings.h>

#define NMONTHS 3
#define MAXLEN 10

#define STRIP(a) (a[strlen(a)-1] = '\0')

int
main (int argc, char *argv[])
{
  /* BETTER: this allocates both the pointers (months[NMONTHS])
             and space for the strings (months[][MAXLEN+1]) */
  char months[NMONTHS][MAXLEN+1];

  int i;

  /* Reading the data to the array */
  for (i=0; i<NMONTHS; i++)
  {
    printf ("Enter next month: ");
    fgets (months[i], MAXLEN, stdin);
    STRIP (months[i]);
  }

  /* printing the Data (eg. January, February, March, ...) */
  for (i=0; i<NMONTHS; i++)
  {
    printf("months[%d]: %s\n", i, months[i]);
  }

  /* Done */
  return 0;
}
SAMPLE OUTPUT:
Quote:
Enter next month: Jan
Enter next month: Feb
Enter next month: Mar
months[0]: Jan
months[1]: Feb
months[2]: Mar
BETTER: (Allocates as needed, no built-in limits on #/entries):
Code:
#include <stdio.h>
#include <strings.h>

#define NMONTHS 3
#define MAXLEN 10

#define STRIP(a) (a[strlen(a)-1] = '\0')

int
main (int argc, char *argv[])
{
  char *months[MAXLEN+1];
  char buff[MAXLEN+1];
  int i;
  int nmonths = 0;

  /* Reading the data to the array */
  for ( ;; )
  {
    printf ("Enter next month, or \"<Enter>\" to exit: ");
    fgets (buff, MAXLEN, stdin);
    if (strlen (buff) <= 1)
    {
      printf ("End of data entry!\n");
      break;
    }
    months[nmonths] = (char *)malloc (strlen (buff));
    if (!months[nmonths])
    {
      printf ("ERROR: Unable to alloc memory!\n");
      break;
    }
    else
    {
      STRIP (buff);
      strcpy (months[nmonths++], buff);
    }
  }

  /* printing the Data (eg. January, February, March, ...) */
  for (i=0; i<nmonths; i++)
  {
    printf("months[%d]: %s\n", i, months[i]);
  }

  /* Done */
  return 0;
}
SAMPLE OUTPUT:
Quote:
Enter next month, or "<Enter>" to exit: Jan
Enter next month, or "<Enter>" to exit: Feb
Enter next month, or "<Enter>" to exit: Mar
Enter next month, or "<Enter>" to exit:
End of data entry!
months[0]: Jan
months[1]: Feb
months[2]: Mar

Last edited by paulsm4; 07-05-2006 at 09:38 PM.
 
Old 07-05-2006, 01:29 PM   #8
linuxlover1
Member
 
Registered: Jun 2003
Location: UK
Posts: 54

Original Poster
Rep: Reputation: 15
Thx a lot men !
hey paulsm4 the 3rd way is really cool.
The 1st has problem, i've tryied it in the past
here's a simple solution for the 2nd one.
Code:
#include <stdio.h>
int main() {
  char months[3][20];
  char (*p)[20];
  int i,j;
  p=months;
  printf("Starting....\n");
  for (i=0;i<=2;++i) { 
     printf("Give %d month: ",i);
     scanf("%s",p);
    ++p;
  }
 --p;--p;--p;
  for (i=0;i<=2;++i) { 
     printf("Month %d=%s\n",i,p);
     ++p;
   }
  return(0);
}

Last edited by linuxlover1; 07-05-2006 at 01:31 PM.
 
Old 07-05-2006, 02:13 PM   #9
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by linuxlover1
Thx a lot men !
hey paulsm4 the 3rd way is really cool.
The 1st has problem, i've tryied it in the past
here's a simple solution for the 2nd one.
Code:
#include <stdio.h>
int main() {
  char months[3][20];
  char (*p)[20];
  int i,j;
  p=months;
  printf("Starting....\n");
  for (i=0;i<=2;++i) { 
     printf("Give %d month: ",i);
     scanf("%s",p);
    ++p;
  }
 --p;--p;--p;
  for (i=0;i<=2;++i) { 
     printf("Month %d=%s\n",i,p);
     ++p;
   }
  return(0);
}
If you really want to do it that way then why all the "p's"?
Code:
#include <stdio.h>
int main(int argc, char* argv[ ])
{
	int i;
	char months[3][20];
	printf("Starting....\n");
	for (i=0;i<=2;++i) 
	{ 
		printf("Give %d month: ",i);
		scanf("%s",months +i);
	}
	for (i=0;i<=2;++i) 
	{ 
		printf("Month %d=%s\n",i,months +i);
	}
	return(0);
}
[edit]
Quote:
...i've started to learning C...
Sorry.

Last edited by dmail; 07-05-2006 at 02:20 PM.
 
Old 07-05-2006, 04:11 PM   #10
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by linuxlover1
i just wander , is there any way to do it using an array of pointers instead of a 2D array ??
No. Not really.
Because in C a string is an array of chars, an array of string is an array of arrays of chars.

Using other method's like with malloc() or calloc() you may not see this directly in code, but it does not in change the fact that strings are arrays of chars.
 
Old 07-05-2006, 05:23 PM   #11
spooon
Senior Member
 
Registered: Aug 2005
Posts: 1,755

Rep: Reputation: 51
Quote:
Originally Posted by Hko
No. Not really.
Because in C a string is an array of chars, an array of string is an array of arrays of chars.

Using other method's like with malloc() or calloc() you may not see this directly in code, but it does not in change the fact that strings are arrays of chars.
No. That is not true. An array of arrays is very different from an array of pointers, even though the syntax for referencing an element is similar. In an array of arrays all the subarrays are consecutive (since it's an array). But in an array of pointers, the pointers can point to subarrays in random places in memory, without any order. In addition, the type signatures of an array of arrays is very different from an array of pointers (the former is a pointer to an array, the latter is a pointer to a pointer).
 
Old 07-05-2006, 05:30 PM   #12
linuxlover1
Member
 
Registered: Jun 2003
Location: UK
Posts: 54

Original Poster
Rep: Reputation: 15
Yea you are right....
 
Old 07-05-2006, 05:37 PM   #13
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by spooon
No. That is not true. An array of arrays is very different from an array of pointers, even though the syntax for referencing an element is similar. In an array of arrays all the subarrays are consecutive (since it's an array). But in an array of pointers, the pointers can point to subarrays in random places in memory, without any order. In addition, the type signatures of an array of arrays is very different from an array of pointers (the former is a pointer to an array, the latter is a pointer to a pointer).
True. You're right about that it's not an 2D arrays in terms of how it is stored in memory. Even though it is possible to write C code that demonstrates the difference, from a C code perspective there's no visible difference. Also keep in mind the OP is a beginner at C.
 
Old 07-05-2006, 06:41 PM   #14
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
Originally Posted by Hko
True. You're right about that it's not an 2D arrays in terms of how it is stored in memory. Even though it is possible to write C code that demonstrates the difference, from a C code perspective there's no visible difference. Also keep in mind the OP is a beginner at C.
Sorry about it but I disagree with the fact a beginner should be taught incorrect statements, especially in such a confusing area.

C pointers and arrays are sometimes similar, but are fundamentally differents in the way they are initialized, affected and stored, even from a C code perspective.

A C programmer has to know what kind of variables he is dealing with.

Code:
  char a[8]; // array
  char *p;   // pointer

  a="test";         // doesn't compile, 'a' cannot be affected, being immutable
  strcpy(a,"test"); // OK, 'a' can (need to here) be overwritten
  strcpy(p,"test"); // run time error, 'p' is uninitialized
  p="test";         // 'p' must be affected, as it initially point to nothing sensible

  printf("%s\n",a); // here 'a' and 'p' are used a similar way
  printf("%s\n",p);

  strcpy(p,"abcd"); // this may or may not work, depending on the compiler implementation and options used
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
About pointers RHLinuxGUY Programming 4 11-15-2005 04:47 PM
pointers in c++ marios_auth Programming 1 06-16-2004 08:20 AM
Pointers Pointers Pointers urzumph Programming 9 03-11-2004 09:49 AM
Looking for some pointers... p3ngu!n Linux - Newbie 17 10-30-2003 06:46 AM
need help with pointers qanopus Programming 8 02-03-2003 05:09 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration