Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Copying string till newline

Reply
Thread Tools

Copying string till newline

 
 
arnuld
Guest
Posts: n/a
 
      09-01-2010
WANTED: To write a function like strcpy(). Unlike strcpy() it copies till
a newline occurs.

GOT: It is working fine. Just want to have any ideas for improvement




#include <stdio.h>

enum { SIZE_ARR = 20 };

int string_copy_till_newline(char dest[], char src[]);


int main(void)
{
char arr_dest[SIZE_ARR]; /* intentionally not initialized with NULLs.
Check the intended function definition */
char arr_src[] = "This is\n an Array\n";

printf("arr_dest = %s\n", arr_dest);
printf("arr_src = %s\n", arr_src);
printf("\n\n------------------------------\n\n");
string_copy_till_newline(arr_dest, arr_src);
printf("arr_dest = %s\n", arr_dest);
printf("arr_src = %s\n", arr_src);

return 0;
}


/* Will copy contents from SRC to DEST till a newline occurs, will not
include newline, puts a NULL character at the end.
returns number of characters copied, else -1 on error. Will write
beyond the array, size checking is user's responsibility */
int string_copy_till_newline(char dest[], char src[])
{
int idx;

if(NULL == dest || NULL == src)
{
printf("IN: %s at %d: One of the arguments is NULL\n", __func__,
__LINE__);
return -1;
}

for(idx = 0; src[idx] != '\n'; ++idx)
{
dest[idx] = src[idx];
}

dest[idx] = '\0';

return idx;
}


==================== OUTPUT ==========================
[arnuld@dune TEST]$ gcc -ansi -pedantic -Wall -Wextra string-copy-till-
newline.c
[arnuld@dune TEST]$ ./a.out
arr_dest = %Ψ
arr_src = This is
an Array



------------------------------

arr_dest = This is
arr_src = This is
an Array

[arnuld@dune TEST]$





--
www.lispmachine.wordpress.com
my email is @ the above blog.

 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      09-01-2010
arnuld <(E-Mail Removed)> wrote:
> WANTED: To write a function like strcpy(). Unlike strcpy() it copies till
> a newline occurs.


> GOT: It is working fine. Just want to have any ideas for improvement


Unfortunately it's working fine only for your test input...

> #include <stdio.h>


> enum { SIZE_ARR = 20 };


> int string_copy_till_newline(char dest[], char src[]);



> int main(void)
> {
> char arr_dest[SIZE_ARR]; /* intentionally not initialized with NULLs.
> Check the intended function definition */
> char arr_src[] = "This is\n an Array\n";


> printf("arr_dest = %s\n", arr_dest);


Since 'dest' is unitialized this is WRONG, printf() has no way
to figure out when to stop printing chars from 'arr_dest'. You
rely on a '\0' char being somewhere in the uninitialized array
by accident.

> printf("arr_src = %s\n", arr_src);
> printf("\n\n------------------------------\n\n");
> string_copy_till_newline(arr_dest, arr_src);
> printf("arr_dest = %s\n", arr_dest);
> printf("arr_src = %s\n", arr_src);


> return 0;
> }


> /* Will copy contents from SRC to DEST till a newline occurs, will not
> include newline, puts a NULL character at the end.
> returns number of characters copied, else -1 on error. Will write
> beyond the array, size checking is user's responsibility */


> int string_copy_till_newline(char dest[], char src[])
> {
> int idx;


> if(NULL == dest || NULL == src)
> {
> printf("IN: %s at %d: One of the arguments is NULL\n", __func__,
> __LINE__);
> return -1;
> }


> for(idx = 0; src[idx] != '\n'; ++idx)
> {
> dest[idx] = src[idx];
> }


Did you consider what happens if there's no '\n' in the source
string? Then you will copy the final '\0' and continue to copy
and copy and copy....

So this needs to be

for ( idx = 0; src[ idx ] != '\0' && src[ idx ] != '\n'; ++idx )
dest[ idx ] = src[ idx ];

> dest[idx] = '\0';


> return idx;
> }

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Nick Keighley
Guest
Posts: n/a
 
      09-01-2010
On 1 Sep, 07:23, arnuld <(E-Mail Removed)> wrote:

> WANTED: To write a function like strcpy(). Unlike strcpy() it copies till
> a newline occurs.
>
> GOT: It is working fine. Just want to have any ideas for improvement
>
> #include <stdio.h>
>
> enum { SIZE_ARR = 20 };
>
> int string_copy_till_newline(char dest[], char src[]);


int string_copy_till_newline(char dest[], const char src[]);

consider returning a char*, say to the end of the dest, this can make
chaining calls together easier.

technically string_copy_till_newline is in a reserved namespacwe
(anything beginning "str" is reserved for the implementation.

consider using C99's "restrict" (though using it marginally reduces
portability)

> int main(void)
> {
> * char arr_dest[SIZE_ARR]; */* intentionally not initialized with NULLs.
> Check the intended function definition */
> * char arr_src[] = "This is\n an Array\n";
>
> * printf("arr_dest = %s\n", arr_dest);
> * printf("arr_src = %s\n", arr_src);
> * printf("\n\n------------------------------\n\n");
> * string_copy_till_newline(arr_dest, arr_src);
> * printf("arr_dest = %s\n", arr_dest);
> * printf("arr_src = %s\n", arr_src);
>
> * return 0;
>
> }
>
> /* Will copy contents from SRC to DEST till a newline occurs, will not
> include newline, puts a NULL character at the end.
> * *returns number of characters copied, else -1 on error. Will write
> beyond the array, size checking is user's responsibility */
> int string_copy_till_newline(char dest[], char src[])
> {
> * int idx;
>
> * if(NULL == dest || NULL == src)
> * * {
> * * * printf("IN: %s at %d: One of the arguments is NULL\n", __func__,
> __LINE__);


some people would frown on a library routine that produced error
messages. Some would prefer errors to go to stderr


> * * * return -1;
> * * }
>
> * for(idx = 0; src[idx] != '\n'; ++idx)
> * * {
> * * * dest[idx] = src[idx];
> * * }


or more idiomatically

while (*src != '\n')
*dst++ = *src++;

I note you don't copy the \n is taht intended?

I'd also worry about what happened if there were no \n in the string.
If src is a string (ie. has \0 at the end) then I'd check for that.

while (*dst++ = *src++)
if (src == '\n')
break;

> * dest[idx] = '\0';
>
> * return idx;
>
> }


<snip>
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      09-01-2010
> On Wed, 01 Sep 2010 06:49:31 +0000, Jens Thoms Toerring wrote:
>> arnuld <(E-Mail Removed)> wrote:


>> printf("arr_dest = %s\n", arr_dest);


> Since 'dest' is unitialized this is WRONG, printf() has no way to figure
> out when to stop printing chars from 'arr_dest'. You rely on a '\0' char
> being somewhere in the uninitialized array by accident.


So, array initialization is should always be used in C before using the
array ?




>> for(idx = 0; src[idx] != '\n'; ++idx)
>> {
>> dest[idx] = src[idx];
>> }


> Did you consider what happens if there's no '\n' in the source string?
> Then you will copy the final '\0' and continue to copy and copy and
> copy....


> So this needs to be
>
> for ( idx = 0; src[ idx ] != '\0' && src[ idx ] != '\n'; ++idx )
> dest[ idx ] = src[ idx ];
>
>> dest[idx] = '\0';

>
>> return idx;



I also know the size of dest, so how about using this condition:

for(idx=0; idx < SIZE_ARR; ++idx)

??




--
www.lispmachine.wordpress.com
my email is @ the above blog.

 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      09-01-2010
arnuld <(E-Mail Removed)> wrote:
> > On Wed, 01 Sep 2010 06:49:31 +0000, Jens Thoms Toerring wrote:
> >> arnuld <(E-Mail Removed)> wrote:


> >> printf("arr_dest = %s\n", arr_dest);

>
> > Since 'dest' is unitialized this is WRONG, printf() has no way to figure
> > out when to stop printing chars from 'arr_dest'. You rely on a '\0' char
> > being somewhere in the uninitialized array by accident.


> So, array initialization is should always be used in C before using the
> array ?


Yes, of course, what sense would it make to use elements of
an array that never were initialized (except maybe when you
want to write a really horribly bad random generator?)

And in the case you were using it you did rely on the array
having a '\0' value somewhere by mere chance - if that's
not the case printf() accesess elements beyond the end of
the array, which is forbidden.

> >> for(idx = 0; src[idx] != '\n'; ++idx)
> >> {
> >> dest[idx] = src[idx];
> >> }

>
> > Did you consider what happens if there's no '\n' in the source string?
> > Then you will copy the final '\0' and continue to copy and copy and
> > copy....

>
> > So this needs to be
> >
> > for ( idx = 0; src[ idx ] != '\0' && src[ idx ] != '\n'; ++idx )
> > dest[ idx ] = src[ idx ];
> >
> >> dest[idx] = '\0';

> >
> >> return idx;



> I also know the size of dest, so how about using this condition:


> for(idx=0; idx < SIZE_ARR; ++idx)


And what would that help you? You explicitely stated that
you want to stop copying at the first '\n' (and, since you're
dealing with strings you must stop after the first '\0' you
encounter). And then that's the length of the destination
array - you must also take that into consideration, since
you're not allowed to write past the end of the destination
array if the source string is too long - but if the source
string is shorter then you must stop at the end of the source
string or you would access elements past the end of that array.

So the correct form, when also taking the final length of the
destination array into account would be

for ( idx = 0;
idx < SIZE_ARR - 1 && src[ idx ] != '\0' && src[ idx ] != '\n';
++idx )
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-01-2010
arnuld <(E-Mail Removed)> writes:

> WANTED: To write a function like strcpy(). Unlike strcpy() it copies till
> a newline occurs.
>
> GOT: It is working fine. Just want to have any ideas for improvement
>


I'd suggest looking at standard library functions. Set yourself a
challenge to do it with as little of you own code as possible. The
point being to learn what already there.

<snip>
--
Ben.
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      09-01-2010
> On Wed, 01 Sep 2010 11:01:02 +0100, Ben Bacarisse wrote:

> I'd suggest looking at standard library functions. Set yourself a
> challenge to do it with as little of you own code as possible. The
> point being to learn what already there.



I did not get your point. Best guess is there is some function if C Std.
Lib. that almost matches my requirements of copying till newline ?





--
www.lispmachine.wordpress.com
my email is @ the above blog.

 
Reply With Quote
 
James
Guest
Posts: n/a
 
      09-01-2010
"arnuld" <(E-Mail Removed)> wrote in message
news:4c7df177$0$50446$(E-Mail Removed)...
> WANTED: To write a function like strcpy(). Unlike strcpy() it copies till
> a newline occurs.


Here is a fairly simple approach:


char* copy_to_newline(char const* src,
char* dest)
{
char const* target = strchr(src, '\n');

if (target)
{
memcpy(dest, src, target - src);
dest[target - src] = '\0';
}

else
{
dest[0] = '\0';
}

return dest;
}


[...]


 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      09-01-2010
On 1 Sep, 10:43, (E-Mail Removed) (Jens Thoms Toerring) wrote:
> arnuld <(E-Mail Removed)> wrote:
> > > On Wed, 01 Sep 2010 06:49:31 +0000, Jens Thoms Toerring wrote:
> > >> arnuld <(E-Mail Removed)> wrote:



> > >> * printf("arr_dest = %s\n", arr_dest);

>
> > > Since 'dest' is unitialized this is WRONG, printf() has no way to figure
> > > out when to stop printing chars from 'arr_dest'. You rely on a '\0' char
> > > being somewhere in the uninitialized array by accident.

>
> > So, array initialization is should always be used in C before using the
> > array ?


there must be a sensible value in a variable before you read it and
take action on it. If you printf("%s") a char array it must contain a
valid string. Isn't this like kind of obvious...

<snip>

> > >> * for(idx = 0; src[idx] != '\n'; ++idx)
> > >> * * {
> > >> * * * dest[idx] = src[idx];
> > >> * * }

>
> > > Did you consider what happens if there's no '\n' in the source string?
> > > Then you will copy the final '\0' and continue to copy and copy and
> > > copy....

>
> > > So this needs to be

>
> > > * *for ( idx = 0; src[ idx ] != '\0' && src[ idx ] != '\n'; ++idx )
> > > * * * *dest[ idx ] = src[ idx ];

>
> > >> * dest[idx] = '\0';

>
> > >> * return idx;

>
> > I also know the size of dest, so how about using this condition:
> > *for(idx=0; idx < SIZE_ARR; ++idx)


yuk. If you know the size of dest and want to use that fact you ought
to pass it in as a parameter. How do you sort this out.

void piffle (void)
{
# define SIZE_ARR 7
char dst1 [SIZE_ARR] = "";
char dst2 [SIZE_ARR * 2] = "";

char source [SIZE_ARR * 2] = "woofle dust\n";

string_copy_to_newline (dst1, source);
}

this fails to copy the whole string even though there's room

this might be a better declaration

char *string_copy_to_newline (char *dst,
size_t dst_size, const char *source);

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-01-2010
arnuld <(E-Mail Removed)> writes:

>> On Wed, 01 Sep 2010 11:01:02 +0100, Ben Bacarisse wrote:

>
>> I'd suggest looking at standard library functions. Set yourself a
>> challenge to do it with as little of you own code as possible. The
>> point being to learn what [is] already there.

>
> I did not get your point. Best guess is there is some function if C Std.
> Lib. that almost matches my requirements of copying till newline ?


Yes, almost. It really helps to know the standard library -- not that it's
prefect, it's just that it's always there. The library is as much part
of C as ++ and * but people often neglect to learn it.

The plus side is that it is small compared to some language's standard
libraries.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Hyphenation in string causes newline =?Utf-8?B?QmFobWFu?= ASP .Net 0 08-30-2006 10:03 PM
retain newline when copying contents of attribute dkacher XML 3 03-06-2006 12:38 AM
Remove newline charcters froma string peelman ASP .Net 1 10-18-2005 05:21 PM
string.split and Environment.NewLine question. =?Utf-8?B?QXNoYQ==?= ASP .Net 1 12-30-2004 09:33 AM
newbie having trouble with control structures: loop till recieve string QUIT M. Duijkers Perl 2 12-12-2004 11:02 AM



Advertisments