Thread: Space in Array

  1. #1
    Unregistered
    Guest

    Space in Array

    i have some problem with spaces in Array. i declare array like this
    Code:
    struct student
    {
       char Id[6],address[30],telephone[7];
    };
    id and telephone are fixed numbers
    the problem is when a user inputs address something like 8 chars
    when it saved, it saved some rubbish i suppose because of the free space in address variable which i didn't use .
    How can i solve this problem? any suggestion
    Cheers

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    The "free space" after the string will follow the string's null terminator. It shouldn't give you a problem.

    How are you writing out? Are you "saving" the complete struct? If so:

    ... you should be using binary mode, and fwrite. Like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    	FILE	*fp;
    	struct
    	{
    		char	name[20];
    	} mine;
    
    	strcpy(mine.name, "Hammer");
    
    	if ((fp = fopen("data.dat", "wb")) == NULL)
    	{
    		perror("data.dat");
    		return(1);
    	}
    
    	if ((fwrite(&mine, sizeof(mine), 1, fp)) != 1)
    	{
    		perror("write");
    	}
    
    	fclose(fp);
    
    	return(0);
    }
    When you read it back in (binary, with fread), the spare characters will still be loaded, but as the string is still terminated with a NULL, it is really irrelevant.

    If you are worried about them though, you can always fill the char array with a character of your choice before putting the string into the array:
    Code:
    ...
    memset (mine.name, ' ', 20);
    strcpy(mine.name, "Hammer");
    ...
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Registered User MisterBadger's Avatar
    Join Date
    Mar 2002
    Posts
    16

    Smile

    Hello All...

    The following is a variation on a program which maintains consistent string lengths before writing the array of structures to a text (or binary) file.

    Following each user input, the remainder of the field is space-filled before writing the null terminator as the last character in the string.
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<conio.h>
    #define SPACES "                              "
    #define MAX 3
    
    struct student
    {
    	char Id[6],address[30],telephone[7];
    };
    
    int main()
    {
     char input1[6], input2[30], input3[7];
     int i, len;
     struct student rec[MAX];
    
    /* Enter details */
    
    for(i=0;i<MAX;i++)
    {
     clrscr();
     printf("ENTER STUDENT RECORD:\n\n");
     printf("ID        [     ]\n");
     printf("ADDRESS   [                             ]\n");
     printf("TELEPHONE [      ]");
     fflush(stdin);
     gotoxy(12,3);
     fgets(input1,6,stdin);
     len=strlen(input1);
     strncat(input1,SPACES,(5-len));
     input1[5]=NULL;
     strcpy(rec[i].Id,input1);
     fflush(stdin);
     gotoxy(12,4);
     fgets(input2,30,stdin);
     len=strlen(input2);
     strncat(input2,SPACES,(29-len));
     input2[29]=NULL;
     strcpy(rec[i].address,input2);
     fflush(stdin);
     gotoxy(12,5);
     fgets(input3,7,stdin);
     len=strlen(input3);
     strncat(input3,SPACES,(6-len));
     input3[6]=NULL;
     strcpy(rec[i].telephone,input3);
    
    } /* end for */
    
    /* Display contents for space-filling to end of each field */
    
    clrscr();
    printf("ARRAY CONTENTS:\n\n");
    
    for(i=0;i<MAX;i++)
    printf("STUDENT %d\nId: %s\nAddress: %s\nTelephone: %s\n\n",
      i+1, rec[i].Id, rec[i].address, rec[i].telephone);
    
    printf("END OF RECORDS.");
    
    return 0;
    }
    Does this help??

    I am aware that fflush(stdin) has undefined behaviour. In this case, I found that omitting this line of code resulted in random jumps over the input fields... By including it, the program produced the desired results...

    Salem has often commented:
    > fflush (stdin);
    This isn't standard - or more specifically, the effects are undefined.

    This is better
    while ( getchar() != '\n' ) continue;
    Would he, or any board member, please suggest a line of code to suit my above program and eliminate the undesirable fflush()?

    Look forward to your ideas. Regards from MrB

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >input2[29]=NULL;
    If you're going to do this, you should use
    >input2[29]='\0';

    Why do you want to pad the char arrays with spaces any way? There's not a lot point, imho.

    If you want the output to be padded to a specific length (when you printf() it), you can use format modifiers to set the field width.

    And yes,
    >while ( getchar() != '\n' ) continue;
    is better than fflush()'ing stdin. But you will have problems as the newline char has most likely been eaten already by the previous fgets() call, and will leave the prompt waiting for one more piece of user input before continuing. This will only be so if the user has entered less characters than the buffer size. If they entered more, the extra characters (and the newline) will still be in the stdin buffer.

    So I'd suggest checking for newline as the last character of the input, and if it's not there, run the above code. EG
    Code:
    if (input1[strlen(input1)-1] != '\n') while ( getchar() != '\n' );
    I'd also suggest you take care of the newline character in your arrays as some may have one in, and some may not.

    Hope this helps.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    >memset (mine.name, ' ', 20);
    >strcpy(mine.name, "Hammer");
    There is a good reason why you might want to do this - namely security

    If you re-use records, you can get information (which is normally hidden from the casual user), leaking out into the file where the more determined snoop will be able to see it.

    Eg.
    If you start with
    strcpy(mine.name, "The President");
    Then later delete that record and re-use it with
    strcpy(mine.name, "Fred");

    The string "resident" will still be in the file, since the only \0 written by the second strcpy will only have overwritten the 'P' of President.

    For MrB
    > fgets(input1,6,stdin);
    > fflush(stdin);
    You shouldn't really read input directly into its final destination - even though you won't overflow the buffer, you can still get invalid data written.

    In addition, if the user types in just one extra char, then you're back into this fflush problem of which you speak.

    Personally, I go for
    char buff[BUFSIZ];
    fgets( buff, BUFSIZ, stdin );

    The user really has to type a lot of excess junk before the code starts to act funny (by which time, it's their problem for not following instructions, not yours). Even then, you could use Hammer's advice of detecting whether there is a \n in the current buffer if you wanted to be extra nice.

    Having got the input in a buffer, and the newline safely dealt with, then you can validate it and move the right amount of data to where it's supposed to go.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  2. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM
  3. Type and nontype parameters w/overloading
    By Mr_LJ in forum C++ Programming
    Replies: 3
    Last Post: 01-02-2004, 01:01 AM
  4. C Filling and Printing a 2-d array
    By Smoot in forum C Programming
    Replies: 3
    Last Post: 11-13-2003, 08:42 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM