LinuxQuestions.org
Review your favorite Linux distribution.
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 05-08-2009, 01:10 PM   #1
j0hnsmith
LQ Newbie
 
Registered: Apr 2009
Posts: 23

Rep: Reputation: 0
C struct string pointer problem


Can someone please explain to me the first program works and the second one doesn't. I struggled for hours wondering what was wrong with the second program.

Works
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
   char currency[80]; // array
}Rate;


void main(void)
{
   Rate rates[1];

   strcpy(rates[0].currency, "one");
   printf("%s\n", rates[0].currency);
   printf("%p\n", &rates[0].currency);

   strcpy(rates[0].currency, "two");
   printf("%s\n", rates[0].currency);
   printf("%p\n", &rates[0].currency);

}
Doesn't work
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
   char *currency; // pointer
}Rate;

void main(void)
{
   Rate rates[1];

   strcpy(rates[0].currency, "one"); // cannot write memory error
   printf("%s\n", rates[0].currency); 
   printf("%p\n", &rates[0].currency);

   strcpy(rates[0].currency, "two");
   printf("%s\n", rates[0].currency);
   printf("%p\n", &rates[0].currency);

}
 
Old 05-08-2009, 01:18 PM   #2
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by j0hnsmith View Post
Can someone please explain to me the first program works and the second one doesn't.
A char* doesn't point anywhere until you give it somewhere to point.

Code:
   char currency[80]; // array
That is a buffer that can hold up to 80 characters.

Code:
   char *currency; // pointer
but that is just an uninitialized pointer.

I'm not sure what you're trying to do. Maybe what you want is:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
   const char *currency; // pointer
}Rate;

void main(void)
{
   Rate rates[1];

   rates[0].currency = "one";
   printf("%s\n", rates[0].currency); 
   printf("%p\n", &rates[0].currency);

   rates[0].currency = "two";
   printf("%s\n", rates[0].currency);
   printf("%p\n", &rates[0].currency);

}
As you've seen, a char buffer is an area you can copy characters into. A char pointer does not point to space you can copy characters into unless you allocate that space. So if you want to copy into or modify the actual characters, using a pointer requires some extra work.

But maybe you don't want to copy into or modify the characters. You just want to point to them. That is something a pointer can do and a buffer can't. That is what I did in the above example.

Notice I changed from char* to const char* to remind you and the compiler that using this method you are not allowed to modify the actual characters. You can modify the pointer to point to some other characters elsewhere, but you can't modify the actual characters.

If you want to use a pointer AND you want to copy to or modify the characters, then you need char* as you originally had, not const char* but you also need to manage the allocation and deletion of the buffer space it points to.

In another thread you said
Quote:
Originally Posted by j0hnsmith View Post
C takes a lot more thought compared to PHP and JavaScript
Are you sure you want to be learning C now? Maybe you should be learning a simpler subset of C++ instead.

C does not have any kind of strings that act like ordinary objects. That can make things very hard for a beginner writing simple programs. Certainly beginners can learn the things I tried to explain at the beginning of this post. But looking at this thread together with that other thread, I suspect that isn't what you want to do at this point.

C++ has a std:string class which handles strings the way a beginning programmer would expect, very much the way these two threads indicate you expected.

You don't need to learn advanced features of C++ to use it instead of C. C++ works very well if you just pretend it is C with the addition of a few conveniences such as strings and streams. Whether your aim is to learn real C or real C++, that subset of C++ can be a better starting place to learn the basics without getting confused by the difficulties of char* and scanf and other beginner vicious aspects of C.

Last edited by johnsfine; 05-08-2009 at 01:42 PM.
 
Old 05-08-2009, 02:09 PM   #3
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
Quote:
Originally Posted by johnsfine View Post
[...]Whether your aim is to learn real C or real C++, that subset of C++ can be a better starting place to learn the basics without getting confused by the difficulties of char* and scanf and other beginner vicious aspects of C.
Oof. I couldn't disagree more. The fundamentals of C are essential to understand any of the complexities (and niceties) of C++, and in particular, the string library.
 
Old 05-08-2009, 07:44 PM   #4
rriggs
Member
 
Registered: Mar 2009
Location: Colorado, US
Distribution: Fedora 13, Fedora 14, RHEL6 Beta
Posts: 46

Rep: Reputation: 17
Quote:
The fundamentals of C are essential to understand any of the complexities (and niceties) of C++
I agree, but from the standpoint of learning to program, C++ can teach high-level programming concepts without getting bogged down in the details of low-level concepts of bytes, arrays, pointers, etc. They are necessary at some point, but I believe the grotty details of C are best avoided at first.
 
Old 05-08-2009, 11:19 PM   #5
j0hnsmith
LQ Newbie
 
Registered: Apr 2009
Posts: 23

Original Poster
Rep: Reputation: 0
Quote:
Are you sure you want to be learning C now? Maybe you should be learning a simpler subset of C++ instead.
I'm doing a HNC in computing and learning C/C++ is part of it. The difficulty is that it's distance learning so I only have text based learning materials, no actual lectures or or face to face or real time discussion with the lecturer or other students to ask questions or clarify anything. I also have Deitel How to Program C (includes C++) which is excellent. Asking questions in this forum is a fast way to clarify any misunderstandings I have, hopefully it will serve as a reference to those who have similar problems in the future. I greatly value the help I receive.


I understand that C++ makes things easier but also that you should learn C before C++. Regardless, I'm finding examples similar to what I find in the course materials.

The example I gave is simple code to highlight the problem I faced, with the rest of the code relating to what I'm doing removed. In this case I'm trying to extract what I can see being done in code examples in a book on a single structure to an array of structures.

My example shows an array with a single element, it should be multiple elements. Once I have the data in a structure I want to use it in various ways.
 
Old 05-09-2009, 06:53 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Pointers are a very important part of C and C++.

Pretty early in learning C or C++, you need to understand the basic concepts of pointers.

The syntax of C and C++ intentionally confuses the differences between a pointer and an array.
If you declare
Code:
int array[100];
int* pointer;
Then (*array) means the same as (array[0]) and (*pointer) means the same as (pointer[0]). The two variables array, and pointer are very different things, but C syntax hides that difference and tends to confuse beginners.

All that is something you need to learn. I just think it is best learned with arrays of ints or arrays of structs, not with arrays of char.

An experienced C or C++ programmer knows that all the same rules apply to arrays or pointers to char. They also know the special case for quoted strings (like nothing similar for arrays of ints or structs).

But a beginner often needs to deal with text strings even before understanding arrays and pointers. Needing to deal with strings as arrays or pointers to char is a lot of extra effort and can require immediate attention to more advanced issues of memory allocation that should be learned later. Much more focused learning would be possible if you have C++ strings and streams available for easy text and I/O as you start learning more fundamental aspects of the language, when you need text and I/O but you don't need to understand what is really happening inside the text and I/O.

Last edited by johnsfine; 05-09-2009 at 06:55 AM.
 
Old 05-09-2009, 07:36 AM   #7
j0hnsmith
LQ Newbie
 
Registered: Apr 2009
Posts: 23

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by johnsfine View Post
But a beginner often needs to deal with text strings even before understanding arrays and pointers. Needing to deal with strings as arrays or pointers to char is a lot of extra effort and can require immediate attention to more advanced issues of memory allocation that should be learned later. Much more focused learning would be possible if you have C++ strings and streams available for easy text and I/O as you start learning more fundamental aspects of the language, when you need text and I/O but you don't need to understand what is really happening inside the text and I/O.
Makes sense to me, some of the lower level bits of C seem to be hindering me.

Thanks
 
Old 05-09-2009, 10:37 AM   #8
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
Well, at this point I'd suggest you look at the malloc function which is called to associate a pointer with a block of actual RAM. From the discussion above, the "difference" between char str[10] and char * str is that catr str[10] is equivalent to char * str;str=(char *) malloc(10 * sizeof(char));

Your problem (as johnsfine pointed out) is that you skipped the essential malloc step in your second block of code.

<edit>
Oh, also: If you do use malloc, don't forget to call free when you're finished using that block of RAM.
</edit>

Last edited by PTrenholme; 05-09-2009 at 10:39 AM.
 
  


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
extern a struct array/pointer strider82 Linux - Kernel 1 04-08-2009 11:57 PM
[C++] struct.string vs. string. Segfault caused. xtothat Programming 7 03-20-2009 05:27 AM
how to pass pointer of struct to function? jinxcat Programming 2 09-01-2005 09:29 AM
struct pointer in C LuderForChrist Programming 2 01-07-2005 07:44 AM
using struct type X as pointer in struct X. worldmagic Programming 1 10-28-2003 02:06 PM

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

All times are GMT -5. The time now is 08:41 AM.

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