Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

"Clearing" a string 6

Status
Not open for further replies.

piked

Programmer
May 7, 2002
14
AU
Very basic question, hoped it'd be in an FAQ under some sort of "handy tip" heading.. not so.

Anyway, so I have a while loop of some description, a string is read in, I analyse it's contents and act accordingly.

At the end of this loop, I want to clear the string, something along the lines of making every character null. Short of an extremely inelegant embedded loop to do just that, what's the handy expert shortcut? one of those things you do one way because it's the most efficient and applies everytime the situation arises.. Any takers?

Setting the first character to null isn't quite the solution i'm looking for, either. I can post some more specific code if required, because I have some that's not working as I'd like it to, but a general solution to the above problem may fix it.
 
hi,
I belive the most elegant,concise,effective mode is

memset( string, 0, sizeof(string) );

no misunderstandings, no loops, no errors !

Probably is not efficient ( often there is not needing
to clear all string), but I belive this is what you wanted)

bye
 
The function memset copies a specific value into a buffer of a given size.

Code:
void* memset( void* buf, int value, size_t size );

Also, lots of UNIX machines have a function called bzero that works like memset, but only with zero (not any given value). I don't know if that's more efficient than memset or just requires less typing.
 
fair enough.

does memset cover input streams? ie. stdin (and obviously it does, being a buffer)

question becomes, then, what is the best way to clear the input buffer.

fflush -never- works. :p

(at least not in it's simplest, fflush(stdin) form)

(just asking to confirm. i'm doing uni 2nd yr level programming adn this sort of thing comes up alot in basic programs.. yet to find a nice little C FAQ that has these handy bits laid out, the sort of stuff that only comes from experience).
 
Well for a FAQ, I would suggest this

> At the end of this loop, I want to clear the string,
First question is why?
In practice, you only NEED to do this if your input function is particularly horrible.

Primary reading of stdin is best performed using
Code:
char buff[BUFSIZ];
while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
    // do stuff with buff
    //
    // no need to clear buff when you're done
    // fgets() is just going to overwrite it anyway if there is more input
    // and if there is no more input, the loop will exit
}

> fflush -never- works.
That's because it is for output streams, and following writes to update streams. For example:
Code:
printf( "Prompt > " );
fflush(stdout);

> does memset cover input streams? ie. stdin (and obviously it does, being a buffer)
No - a stream is not a buffer.
memset works on blocks of memory (like a buffer).

> Setting the first character to null isn't quite the solution i'm looking for,
You would need to post some code then, because memset() seems an expensive cure to a small problem.
 
Code:
char string[81];

/* your while loop */
while()
{
    ......
    ......
    memset(string, '\0', sizeof(string));

    /* agree with salem's code */
    fflush(stdout)
    /*prompting for input*/
}

use fflush()
or there is some services available in assebly, to check standard streams is empty or not
just use that services to clear streams
 
There are a few places that spring to mind where clearing the input string is really important. Obvious one is if you're inputting something that is to be encrypted/decrypted, for instance a password.
If you DON'T clear the string to zeros, then sooner or later it is going to find itself in a random bit of memory that Windows (or similar) decides to cache to the swap file (this may happen long after your program has terminated! The next program's heap isn't automatically cleared to zero....).
And once it's in the swap file, your unencrypted password is sitting there for all to see on the hard disk. It doesn't matter how good your encryption routine is if this happens.
 
Here's the basis of the code:

while (1) {
printf ("Exit loop (E) or Enter full path for execution :\t");
fgets(inp, INPLEN, stdin);
if ((p=strchr(inp, '\n')) != NULL) *p = '\0';
if (strcmp(inp, "E")==0) break;
if ((curpid=fork())==0) {
if (execve(inp, argv, envp)==-1) {
printf ("%s\n", strerror(errno));
}
} else {
waitpid (curpid, &status, 0);
}
}

and the initial problem was, after it'd gone through the loop and executed some program, it'd receive and act on the newline (as input when pressing enter the first time round to put the info into inp), but that's solved by the strchr bit.

now, what's happening, is if execve exits on an error, inp is storing the typo'd input for as many letters are as in that line.

for example: at the prompt, i type in "asfk"
strerror picks that up, prints out no such file/directory error
inp now stores asfk four times round the loop. ie. i hit E straight away after the error comes up, and it repeats the error. I have to hit E another three times before it'll actually respond and store the E to exit the program.

thus the want to clear the string 'inp' once and for bloody all :p
 
Hrrm, no 'edit post' option.

The error, as I report it above, is not quite accurate.. none the less, it's what's happening in essence, and you can see my code to suggest improvements upon, if you'd be so kind :)
 
The problem is, once exec() fails, you've got a fork()'ed process running round the same loop as your main process, reading input and reporting problems.

Code:
      if (execve(inp, argv, envp)==-1) {
         printf ("%s\n", strerror(errno));
      }
      _exit( 1 );  /* make sure this child dies if the exec() fails */
If the exec() succeeds, its a one-way trip - nothing else gets executed in this code, as the program which is being run takes over the child process.

It would also be a good idea to write
Code:
if ( fgets(inp, INPLEN, stdin) == NULL ) break;
 
for possible errors check the ENOMEM Macro for this reason

ENOMEM
Not enough memory is available to execute the new process; or the available memory has been corrupted; or an invalid block exists, indicating that the calling process was not allocated properly
 
Since we touched memset I want to add few words about this treaky function.

It's good for initiating strings with any character, but you also can use it on any array integer, double ... or on any chank of memory, just be carefull!!!

Somehow memset interface is missleading. Second argument (int) is not really an integer.
try do do:
int A[5];
memset (A,1,sizeof(A));
You will get A[0] value set as 16843009
The problem is it reads only first byte and copy it to every byte starting from address of A and since A[0] is (for example) 4 bytes it will copy 1 (00000001) 4 times and get 00000001000000010000000100000001 which is 16843009.
So you will get the same result using:
memset (A,1+256,sizeof(A)); Since first byte is the same for 1 and 1+256. I don't even want to start with doubles.

Now there is only two integer values you can use without fear. One is of cause zero (0), everybody knows it. It will always put only 0 in every bit, but there is obviosly another one wich people often ignore, it's (-1), since it's does not have any zeros -1=11111111 it will put 1 in every bite and always produce -1 in result.

So you can use 0 and -1 to quickly initialize any arrays, not only strings.



 
hi,
when you speak in 'bit' language, the best is speak to computer in Hexadecimal word: all 1 says 0xFF for a byte.

Loading a buffer by memset, usually is done in character arrays. However

int A[5] ;

if we are in a 32 bit processor, sizeof(A) is 20

memset( A, 1, sizeof(A) )

writes 5*4 =20 times the BYTE 1

bye
 
I was talking about 4 bites in one elliment A[0], yes all together it will be 20.
Making my point in HEX would not help to understand how -1 works.
 
Lim,
the power and the limits of C are this.

unsigned char u ;
char c;

u = 0xFF ;
c = 0xFF ;

printf( "%d", u ) ==> 255
printf( "%d", c ) ==> -1

bye
 
No, my favourite:
int a[3];

1[a]=2;
printf("%d",a[1]); ==> 2 :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top