ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
#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
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()?
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.
(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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.