LinuxQuestions.org
Help answer threads with 0 replies.
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-26-2015, 11:14 AM   #1
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Rep: Reputation: Disabled
how to truncate a string


Help needed to understand how to truncate a string using C.
Specific goal is, eg, to be able to truncate a seven char string down to six char, for which I thought strncmp() might be suitable.
Tried using the following code to no avail:
Code:
#include <stdio.h>
#include <string.h>
#define LIM 5
char *strncpy(char *dest, const char *src, size_t n)
{
    size_t i;

    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    for ( ; i < n; i++)
        dest[i] = '\0';
    return dest;
}

int main(void)
{
    char *path[LIM];
    path[1] = "go to sleep";
    printf("s\n",strncpy(path[2],path[1],1));
}
---as it gives garbage output!
Is this an incorrect application for strncmp()? Any corrections or suggestions as to a proper way to accomplish my goal would be appreciated.(should I simply use a for-loop with strlen - 1?).

Last edited by atlantis43; 05-26-2015 at 11:17 AM.
 
Old 05-26-2015, 11:39 AM   #2
jailbait
LQ Guru
 
Registered: Feb 2003
Location: Virginia, USA
Distribution: Debian 12
Posts: 8,337

Rep: Reputation: 548Reputation: 548Reputation: 548Reputation: 548Reputation: 548Reputation: 548
Put a null character (string terminator) after the sixth character in the string.

----------------------
Steve Stites
 
1 members found this post helpful.
Old 05-26-2015, 11:40 AM   #3
veerain
Senior Member
 
Registered: Mar 2005
Location: Earth bound to Helios
Distribution: Custom
Posts: 2,524

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
A corrected code:

Code:
#include <stdio.h>
#include <string.h>
#define LIM 5
char *strncpy(char *dest, const char *src, size_t n)
{
    size_t i;

    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    if ( (src[i] == '\0') || (i == n) ) dest[i] = '\0';
    return dest;
}

int main(void)
{
    char *path[LIM];
    path[1] = "go to sleep";
    printf("%s\n",strncpy(path[2],path[1],1));
}
Run and post status.
 
1 members found this post helpful.
Old 05-26-2015, 11:43 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Code:
#define LIM 5
...
int main(void)
{
    char *path[LIM];
    path[1] = "go to sleep";
    printf("%s\n",strncpy(path[2],path[1],1));
}
You didn't make path[2] (or any of path[0], path[3], path[4]) point anywhere, so they are pointing to some random memory location. Writing to some random location isn't going to work very well.

Also, strncpy() is an existing function in libc, so it's a bit confusing to redefine it (you should call yours my_strncpy or something).

Finally, why are you passing 1 as the length to strncpy()?

Last edited by ntubski; 05-26-2015 at 11:44 AM. Reason: frigging % eating bug
 
1 members found this post helpful.
Old 05-26-2015, 11:47 AM   #5
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by veerain View Post
A corrected code:

Code:
#include <stdio.h>
#include <string.h>
#define LIM 5
char *strncpy(char *dest, const char *src, size_t n)
{
    size_t i;

    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    if ( (src[i] == '\0') || (i == n) ) dest[i] = '\0';
    return dest;
}

int main(void)
{
    char *path[LIM];
    path[1] = "go to sleep";
    printf("%s\n",strncpy(path[2],path[1],1));
}
Run and post status.
Very funny that the code I used was copied & pasted straight from the man pages, yet needed your correction in order to work properly!
 
Old 05-26-2015, 11:50 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
strncmp and strncpy are different, but you need neither.
Code:
    printf ("First five chars: '%.5s'\n", "long long long text");
 
1 members found this post helpful.
Old 05-26-2015, 12:00 PM   #7
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
You didn't make path[2] (or any of path[0], path[3], path[4]) point anywhere, so they are pointing to some random memory location. Writing to some random location isn't going to work very well.
Oh! So that's my screw-up!
Quote:
Also, strncpy() is an existing function in libc, so it's a bit confusing to redefine it (you should call yours my_strncpy or something).
Though I thought it should work in that fashion, when it didn't (now obviously because of the above) I went to man pages and found:
Code:
       A simple implementation of strncpy() might be:

           char *
           strncpy(char *dest, const char *src, size_t n)
           {
               size_t i;

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

               return dest;
           }
----and tried to use that. (From your comment, I now understand why veerain's "code correction" worked)
Quote:
Finally, why are you passing 1 as the length to strncpy()?
Quote:
Just to see it work
 
Old 05-26-2015, 12:04 PM   #8
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jailbait View Post
Put a null character (string terminator) after the sixth character in the string.

----------------------
Steve Stites
I guess that would work as well, if I first copied path[1] to path[2]. Path[1] can't be changed once established.
 
Old 05-26-2015, 12:07 PM   #9
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
strncmp and strncpy are different, but you need neither.
Code:
    printf ("First five chars: '.5s'\n", "long long long text");
But they are not for viewing, but need transfer to another char*. How would using printf() in that context work?
I'm clearly losing my attentiveness to detail. I didn't notice the "strcmp" confusion until you just mentioned it.

Last edited by atlantis43; 05-26-2015 at 12:13 PM.
 
Old 05-26-2015, 12:26 PM   #10
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by atlantis43 View Post
(From your comment, I now understand why veerain's "code correction" worked)
It only works by accident. I guess writing 2 bytes to the random location path[2] is pointing to happens not to break anything important.

The "correction" changes the behaviour of strncpy() such that
Quote:
Originally Posted by man 3 strncpy
If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
no longer applies. So you have a strncpy() that acts a bit differently from the standard strncpy(). It would be better to give it a different name, or else use the standard strncpy() but handle the ending null byte outside the function.
 
Old 05-26-2015, 02:29 PM   #11
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
sprintf is the string-wrinting variant. eg
Code:
char p= buff;
p += sprintf (p, "something=d", intval1);
p += sprintf (p, "str='%.5s', strval1);
...
len= p-buff;
 
2 members found this post helpful.
Old 05-26-2015, 03:01 PM   #12
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by atlantis43 View Post
Help needed to understand how to truncate a string using C.
Specific goal is, eg, to be able to truncate a seven char string down to six char, ...
Code:
seven_char_string[6] = '\0';

Last edited by schneidz; 05-26-2015 at 03:19 PM.
 
1 members found this post helpful.
Old 05-26-2015, 04:30 PM   #13
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by schneidz View Post
Code:
seven_char_string[6] = '\0';
forgot to initially emphasize that I need a 'new' string with the truncated chars in it, as I'd attempted with my submitted code.
 
Old 05-26-2015, 07:42 PM   #14
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Or something like:
Code:
char *new_nstr(char *p, size_t n)
{
    char *q;

    q = calloc(n+1,1);         /* make sure default array is zero filled and
                                  space for terminator */
    if (q) {                   /* protect against basic memory allocation failure */
        if (p) strncpy(q,p,n); /* protect against p being NULL */
        q[n]= '\0';            /* force null terminator if q is length n */
    }
    return (q);
}
Granted some may prefer a "if (NULL != q)" construct instead of "if (q)" for testing a null pointer.

Last edited by jpollard; 05-26-2015 at 07:45 PM.
 
1 members found this post helpful.
Old 05-27-2015, 06:59 AM   #15
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
Or something like:
Code:
char *new_nstr(char *p, size_t n)
{
    char *q;

    q = calloc(n+1,1);         /* make sure default array is zero filled and
                                  space for terminator */
    if (q) {                   /* protect against basic memory allocation failure */
        if (p) strncpy(q,p,n); /* protect against p being NULL */
        q[n]= '\0';            /* force null terminator if q is length n */
    }
    return (q);
}
Granted some may prefer a "if (NULL != q)" construct instead of "if (q)" for testing a null pointer.
Style appreciated. Actually, each new array will have additional chars added to array elements, so I don't think that null terminators are needed immediately following strncpy(), but would be added at a later time.
 
  


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
[SOLVED] truncate to end of line after a specific string threezerous Linux - Newbie 2 09-21-2012 04:49 PM
[SOLVED] copy string a to string b and change string b with toupper() and count the chars beep3r Programming 3 10-22-2010 07:22 PM
truncate help munna_dude Programming 8 10-18-2007 09:24 PM
how can i truncate this munna_dude Linux - Networking 1 06-15-2007 11:42 PM
how to use truncate sureshbabu Linux - Newbie 1 10-29-2003 04:22 AM

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

All times are GMT -5. The time now is 02:52 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