0

I'm having a problem understanding how to read in a string to a structure member array. I have a structure called 'customer' and a member called 'char last_name[20]'. I prompt the user to enter in his last name and that last name is to be stored in the 'last_name[20]' variable. The condition is that I have to use a do...while loop.

Here's the code:

void get_customer_info(struct customer *p_customer_start, int customer_num)
{
   struct customer *p_customer;

   for (p_customer = p_customer_start; (p_customer - p_customer_start) < 
        customer_num; p_customer++)
   {
      printf("\nCustomer number %d: ", (p_customer - p_customer_start) + 1);

      while (getchar() != NEW_LINE); 

      printf("\n   Enter the customer's last name: ");

      // *THIS PART IS THE PROBLEM* 
      do
      {
         p_customer->last_name = getchar();         
         p_customer->last_name++;
      } while (*p_customer->last_name != NEW_LINE);

   }
   return;
}

Problem is, with that algorithm last_name[0] does not get checked, it moves to 'last_name[1]' before it gets checked for a new line. And yes, a do...while construct must be used (this is for a class).

I appreciate anyone's thoughts.

3
  • This won't even compile: you can't assign to or increment arrays; last_name = ... and last_name++ are errors. Commented Nov 2, 2010 at 1:25
  • Ah, sorry, for the assignment it should've been '*p_customer->last_name = getchar();' But that made me realize that constant pointers(names of arrays) can't move, I was thinking of assigning the address of last_name to a pointer, but I'm not sure how to get the address of a structure member.. Commented Nov 2, 2010 at 1:30
  • The increment still won't work. Commented Nov 2, 2010 at 1:32

3 Answers 3

3

I think you may have much bigger problems there than you realise, with the attempted manipulation of an array address :-)

You can probably avoid all these problems with:

int i = 0;
do {
    p_customer->last_name[i++] = getchar();         
} while (p_customer->last_name[i-1] != NEW_LINE);
p_customer->last_name[i] = '\0';

Keep in mind that this is still open to buffer overflow problems (as was your original solution) since entering a name like "Pasquale Voldemort Fortescue del Mor" is going to blow out your 20-character array.

There are ways to fix that but it probably doesn't matter for classwork that much (it will in the real world but that comes with experience):

int i = 0;
do {
    p_customer->last_name[i] = getchar();
    if (i < sizeof (p_customer->last_name) - 1)  // NEVER got to 20
        i++;
} while (p_customer->last_name[i-1] != NEW_LINE);
p_customer->last_name[i] = '\0';

If you really want a pointer version of it, that's easy:

char *p = p_customer->last_name;
do {
    *p = getchar();
    if (p != &(p_customer->last_name[sizeof(p_customer->last_name) - 1])
        p++;
} while (*(p-1) != NEW_LINE);
*p = '\0';
Sign up to request clarification or add additional context in comments.

3 Comments

I understand I can do it that way, but a do...while would then be pointless, I would've just used a for loop. I'm thinking more along the line of pointer arithmetic or some other solution not involving indexes, but thanks anyhow.
Well, you asked for a do...while loop, there it is :-) I see no requirement for pointers. The whole exercise is pointless (other than its educational value) since you would no doubt be using robust input functions in the real world, like this most excellent one over here: stackoverflow.com/questions/1956687/… :-) In any case, I've added a pointer version for you, in case you want to use it instead.
Thanks, that's given me an idea of how to go about it. It is really for non-practical purposes, but I guess it helped me understand pointers and structures a bit better.
0

Ok, the solution with NO INDEXES would be;

char *pointer;

/* other code here */
pointer = p_customer->last_name 
do {
    *pointer = getchar();
    pointer += sizeof( char );
} while ( *(pointer - sizeof( char ) )!= NEW_LINE );

if you want to be sure not to go out of array bound.......simply do not use do while =) (which I always reccomend, as you must read lots of line before understanding the loop condition (and in a multinested function this is't a real readibility problem

4 Comments

Why go through the trouble of doing pointer += sizeof( char ) when you can just do pointer++?
If I ever find someone in close physical proximity using sizeof(char) instead of 1, I will go biblical (as in "wrath of ${INSERT_DEITY_OF_CHOICE_HERE}") on them :-)
Haha, what I had in mind was to increment but somehow check for the previous addresses' contents. This fits the logic I was thinking in, and yes, doing pointer++ would complete it.
ok, no need to do pointer += sizeof( char ) instead of pointer++; but as long as john have some problem in understanding pointer aritmethic I tuoght that my solution would be a little bit cleaner then a (faster buy less understandable) pointer++ :]
0

The code you posted won't compile. You mentioned that last_name is an array, but you can't assign to or increment arrays, so these two lines are invalid:

p_customer->last_name = getchar();         
p_customer->last_name++;

Try doing something like this, which will get rid of this error as well as solve the problem of checking if the first character is a newline:

int i = 0;
char ch;

while ((ch = getchar()) != NEW_LINE)
  p_customer->last_name[i++] = ch;

p_customer->last_name[i] = '\0';  // Don't forget the null terminator

1 Comment

I mentioned that it needed to be a do...while.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.