Insert hyphens after fifth character in C - c

I have a char array, and I want to insert hyphens after every five characters. I have tried the following code but am looking for a better way to accomplish this task, what string function should I use, and how? Thanks. :D
#include <stdio.h>
#include <string.h>
int main()
{
char str[]="356a192b7913b04c54574d18c28d46e6395428ab";
char buf[50];
sprintf(buf, "%.5s-%.5s-%.5s-%.5s-%.5s-%.5s-%.5s-%.5s",str, str+5,str+10,str+15,str+20,str+25,str+30,str+35,str+40);
printf("%s",buf);
return 0;
}

You know you want (length - 1) / 5 hyphens. So for buf, you need storage for buf[len + (len -1) / 5 + 1]; characters. Then simply loop over the characters in str and (skipping the case where i = 0) if i % 5 == 0 write a hyphen to buf in addition to copying the character from str.
Putting it together, you can do something similar to:
#include <stdio.h>
#include <string.h>
#define HYPHPOS 5
int main(void) {
char str[] = "356a192b7913b04c54574d18c28d46e6395428ab";
size_t len = strlen (str);
char buf[len + (len -1)/ HYPHPOS + 1], *p = buf;
for (size_t i = 0; i < len; i++) {
if (i && i % HYPHPOS == 0)
*p++ = '-';
*p++ = str[i];
}
*p = 0;
printf ("str : %s\nbuf : %s\n", str, buf);
return 0;
}
You can also simply use str[i] as the loop test clause.
Example Use/Output
$ ./bin/hyphenate
str : 356a192b7913b04c54574d18c28d46e6395428ab
buf : 356a1-92b79-13b04-c5457-4d18c-28d46-e6395-428ab
Look things over and let me know if you have further questions.

Here's a helper function I whipped up for you. It takes a string as a parameter along with the desired hyphens spacing and returns a new string with hyphens within it. Notice it makes sure that there's no trailing hyphens at the end of the string.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* hyphenize(const char* str, int spacing)
{
size_t len, newlen;
char *ptr, *buf;
if (spacing < 1)
{
return NULL; // error!
}
len = strlen(str);
newlen = len + (len / spacing) + 1;
buf = (char*)malloc(newlen);
ptr = buf;
for (size_t x = 0; x < len; x++)
{
*ptr++ = str[x];
if ((x != 0) && (x != (len - 1)) && ((x + 1) % spacing == 0))
{
*ptr++ = '-';
}
}
*ptr = '\0';
return buf;
}
int main()
{
char str[] = "356a192b7913b04c54574d18c28d46e6395428ab";
char* p = hyphenize(str, 5);
printf("%s\n", p);
free(p);
return 0;
}

Related

Can only write to first element of char** buffer

I'm quite new to C and am trying to write a function, which will split a string into an array of strings at a specific delimiter. But strangely I can only write at the first index of my char** array of strings, which will be my result. For example if I want to split the following string "Hello;;world;;!" at ;; I get [ "Hello" ] instead of [ "Hello", "world", "!" ]. I can't find my mistake.
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "strings.h"
int split(char **dest, const char *src, const char *splitStr) {
char buffer[16384];
int counter = 0;
int len = strlen(splitStr);
int flag = 0;
int start = 0;
for (int i = 0; i < strlen(src); i++) {
flag = 0;
if (src[i] == splitStr[0]) {
for (int j = 1; j < len; j++) {
//check if all elements in delimiter are in string
if (src[i + j] == splitStr[j] && j != (len - 1)) {
continue;
}
else if(src[i + j] == splitStr[j] && j == (len - 1)) {
buffer[i] = '\0';
dest[counter] = malloc(sizeof(char) * (i - start + 1));
strncpy(dest[counter], buffer + start, (i - start));
start = i + (len-1)
flag = 1;
i += (len - 1);
counter++;
}
//if not break
else {
break;
}
}
}
if (i == (strlen(src) - 1)) {
buffer[i] = src[i];
buffer[i + 1] = '\0';
counter++;
break;
}
if (flag == 0) {
buffer[i] = src[i];
}
}
return counter;
}
A proper function call would look like this:
auto src = "Hello;;world;;!";
auto buffer = (char **)malloc(32);
int count = split(buffer, src, ";;");
The buffer should contain, all the splitted strings, more or less like this: [ "Hello", "world", "!" ].
Currently my result buffer looks like this in the debugger. It appears as only the first element is written into it.
There are multiple problems in your code:
you compute string lengths repeatedly, which may be very inefficient. Instead of testing i < strlen(src) you should write src[i] != '\0'.
your test for check a matching delimiter is too complicated. You should use strstr to locate the delimiter string in the remaining portion of the string.
strncpy does not do what you think: strncpy(dest[counter], buffer + start, (i - start)); should be replaced with memcpy(dest[counter], buffer + start, i - start); and you must set the null terminator explicitly: dest[counter][i - start] = '\0'; You should read why you should never use strncpy().
it is unclear why you use buffer at all.
Here is a modified version:
#include <stdlib.h>
#include <string.h>
/* if POSIX function strndup() is not defined on your system, use this */
char *strndup(const char *str, size_t n) {
size_t len;
for (len = 0; len < n && str[len] != '\0'; len++)
continue;
char *s = malloc(len + 1);
if (s != NULL) {
memcpy(s, str, len);
s[len] = '\0';
}
return s;
}
int split(char **dest, const char *src, const char *splitStr) {
const char *p = str;
const char *end;
int counter = 0;
size_t len = strlen(splitStr);
if (len == 0) {
/* special case */
while (*p != '\0') {
dest[counter++] = strndup(p++, 1);
}
} else {
while ((end = strstr(p, splitStr)) != NULL) {
dest[counter++] = strndup(p, end - p);
p = end + len;
}
dest[counter++] = strdup(p);
}
return counter;
}
First of all you are not updating the start variable after you have copied the first string.
For simple debugging I would recommend adding some printf statements to see what is going on.
Proper formatting is not to be underestimated to make the code easy to read and easier to debug.
Also it is not clear what the buffer is for, and I think you can do without it.
The tips in the comments are also good. Split the function into smaller pieces and structure your code so it is simple to read.
A suggestion is to write a function to find the index of the next split string and the end of the string. Then you can use that to get the index and length you need to copy.

How do I remove a character at an index in c?

This is my program:
Does anyone know why it doesn't work?
My professor asked me to remove a character at an index using pointers, I'm also not allowed to use a for - loop so I'm kind of lost.
int count = 0;
int strl = strlen(s);
char s2 [strl-1];
if (index >= 0 && index < strl){
while(count < strl){
if (count == index){
*(s+index) == *s;
strl--;
}
count++;
}
printString(s);
}
}
Your program won't work because your program don't modify strings.
You can use memmove() to shift the string after the character to be removed left by one character to remove a character. (Pointers are used as the arguments of memmove())
#include <stdio.h>
#include <string.h>
void removeAt(char* str, int idx) {
size_t len = strlen(str);
memmove(str + idx, str + idx + 1, len - idx);
}
int main(void) {
char target[] = "0123456789";
printf("before removing : %s\n", target);
removeAt(target, 5);
printf("after removing : %s\n", target);
return 0;
}
Output:
before removing : 0123456789
after removing : 012346789
In order to remove a character at index i from a string you need to move every character after it one space back:
void remove_at(char* s, size_t i) {
if (!s) return;
while (s[i]) {
s[i] = s[i+1];
i++;
}
}
It's undefined behavior to pass an i >= strlen(s), so beware.
Here is an example using pointers to delete a character at a specific index in a string:
#include <assert.h>
#include <stdio.h>
#include <string.h>
void DeleteChar(int index, char string[])
{
char *ptr;
assert(index >= 0);
assert(index < strlen(string));
ptr = string + index;
while (*ptr != '\0') {
*ptr = *(ptr + 1);
ptr++;
}
}
int main(void)
{
char string[] = "hello world";
DeleteChar(9, string);
puts(string);
return 0;
}
Note, however, that it is safer and simpler to use only indices instead of pointers.

Not showing only few chars when connecting strings [duplicate]

This question already has answers here:
Sizeof vs Strlen
(4 answers)
Closed 3 years ago.
I have simple function that should connect string but in different way.
If i have one string "abc" and another "123" final string should be "a1b2c3".
Here is code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
char *connStrings(char *s1, char *s2) {
int s1L, s2L,i = 0,k=1,j=0;
s1L = sizeof(s1);
s2L = sizeof(s2);
char* result = (char*) malloc((s1L + s2L));
while (s1[i] != '\0') {
result[j] = s1[i++];
j = j + 2;
}
i = 0;
while (s2[i] != '\0') {
result[k] = s2[i++];
k = k + 2;
}
result[s1L + s2L] = '\0';
printf("\n %s \n", result);
}
int main() {
connStrings("abcdefghi","123456789");
}
So what's the problem?
the final output of this program is still the same "a1b2c3d4e5f6g7h8"
It ignores i and 9 somehow. Even if I add more chars into both strings it still prints the same
"a1b2c3d4e5f6g7h8". I will be thankful for any help or advice.
Use proper function return type and strlen instead of sizeof
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
void connStrings(char *s1, char *s2) {
int s1L, s2L, i = 0, k = 1, j = 0;
s1L = strlen(s1);
s2L = strlen(s2);
char *result = (char *) malloc((s1L + s2L + 1 )); // extra one for the `null` terminator `\0`
while (s1[i] != '\0') {
result[j] = s1[i++];
j = j + 2;
}
i = 0;
while (s2[i] != '\0') {
result[k] = s2[i++];
k = k + 2;
}
result[s1L + s2L + 1] = '\0';
printf("\n %s \n", result);
// free memory when you're done
free(result);
}
int main() {
connStrings("abcdefghi", "123456789");
return 0; // or use void
}
When you pass an array as an argument to a function, what you're really passing is a pointer to the first element of the array.
sizeof will not return the length of the buffer in this case, but the size of a pointer.
Fortunately, C strings have the useful property of being terminated with a null character ('\0'), which allows functions like strlen to give you the actual length of the string, even when all you have is a pointer and not the array. strlen works similar to this:
size_t strlen(char *s)
{
size_t ret = 0;
while(*s) ret++, s++;
return ret;
}
Even when calculating the length of a string when you have an actual array, you still shouldn't use sizeof because that will return the entire size of the buffer, which may not be the length of the string within it.
Consider: char s[100] = "Hello World";
sizeof s would be 100; strlen(s) would return 11.

Converting Integer to dynamically allocated Char array, digit by digit using pointers

I need to convert Integer to Char, I can use only pointers without array indexes. Char array must be dynamically allocated. Can anybody review my code and tell my what am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
int main(){
int myNumber = 1234;
char *myString = (char*)malloc(2 * sizeof(char)); //memory for 1 char and '\0'
int i = 0; //parameter for tracking how far my pointer is from the beggining
if (myNumber < 0){
*myString = '-'; //if myNumber is negative put '-' in array
*myString = *(myString + 1); //move pointer to next position
i++;
}
while (myNumber != 0){
myString = (char*)realloc(myString, (i + 2) * sizeof(char)); //increse memory =+1
*myString = (myNumber % 10) + '0'; //put digit as char to array
myNumber /= 10;
*myString = *(myString + 1); //move pointer to next position
i++;
}
*myString = '\0'; //mark end of string
*myString = *(myString - i); //move pointer back to the beggining of string
printf("\n%s", *myString); // print char array (not working..)
return 0;
}
I know there are better ways of converting Int to String (sprintf), but my task is to do it that way.
In the code above I`m taking the digits from Int backwards, can it be done in correct order?
edit. as mentioned in the comments the part:
*myString = *(myString + 1);
is wrong, correct way of redirecting pointer by one space is:
myString++;
same with:
*myString = *(myString - i); //wrong
myString -=i; //ok
Edit2:
Now my code works! But I need to think how to correct the order of the digits.
#include <stdio.h>
#include <stdlib.h>
int main(){
int myNumber = 1234;
char *myString = (char*)malloc(2 * sizeof(char)); //memory for 1 char and '\0'
char * position = myString;
int i = 0;
if (myNumber < 0){
*position = '-'; //if myNumber is negative put '-' in array
position += i; //move pointer to next position
i++;
}
while (myNumber != 0){
myString = (char*)realloc(myString, ((i + 2) * sizeof(char))); //increse memory =+1
position = myString + i; // getting current position after reallocating
*position = (myNumber % 10) + '0'; //put digit to array
myNumber /= 10;
position++; //move pointer to next position
i++;
}
*position = '\0'; //mark end of string
char * temp = myString;
while (*temp != '\0'){
printf("%c", *temp); // print char array (not working..)
temp++;
}
return 0;
}
Edit 3 Problem solved, thanks for comments, I`m posting code in case anybody will look for similar solution.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// move each character in array one place to the right
// we need to make place for new character on the left
void moveArrayElementsRight(char *ptr, int len) {
for (int j = len; j > 1; j--) {
*(ptr + j - 1) = *(ptr + j - 2);
}
}
void intToStr(int myNumber, char* myString){
int i = 1; //track size of allocated memory
bool isMinus = false;
if (myNumber < 0) {
myNumber *= -1; //without this (myNumber % 10) + '0' wont work
isMinus = true;
}
if (myNumber == 0){ //special case for 0
myString = (char*)realloc(myString, ((i + 1) * sizeof(char)));
*myString = '0';
*(myString + 1) = '\0';
}
while (myNumber != 0) {
myString = (char*)realloc(myString, ((i + 1) * sizeof(char))); //increse memory =+1 for next digit
i++;
moveArrayElementsRight(myString, i);
*myString = (myNumber % 10) + '0'; //put digit to array
myNumber /= 10;
}
if (isMinus) {
myString = (char*)realloc(myString, ((i + 1) * sizeof(char))); //increse memory =+1 for '-' sign
i++;
moveArrayElementsRight(myString, i);
*myString = '-'; //put sign at the beginning
}
}
int main() {
int numberToConvert = -10;
char *numberAsString = (char*)malloc(sizeof(char)); //create empty array, with place only for '\0'
*numberAsString = '\0'; //mark the end of array
intToStr(numberToConvert, numberAsString);
printf("%s", numberAsString);
return 0;
}
SPOILER: Don't read or copy this if you don't want the solution.
The following is an example of implementation, using recursive:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#include <errno.h>
static size_t int_to_str_size(int n, size_t acc, int base_size) {
int next = n / base_size;
if (next != 0) {
return int_to_str_size(next, acc + 1, base_size);
} else {
return n < 0 ? acc + 2 : acc + 1;
}
}
static void int_to_str_write(int n, char *str, char *base, int base_size) {
*str = base[abs(n % base_size)];
int next = n / base_size;
if (next != 0) {
int_to_str_write(next, str - 1, base, base_size);
} else {
if (n < 0) {
*(str - 1) = '-';
}
}
}
static char *int_to_str(int n, char *base) {
size_t base_size = strlen(base);
if (base_size < 2 || base_size > INT_MAX) {
errno = EINVAL;
return NULL;
}
size_t size = int_to_str_size(n, 0, (int)base_size);
char *str = malloc(size + 1);
if (str == NULL) {
return NULL;
}
str[size] = '\0';
int_to_str_write(n, str + size - 1, base, (int)base_size);
return str;
}
int main(void) {
srand((unsigned int)time(NULL));
for (uintmax_t i = 0; i < 42; i++) {
int n = rand() % 2 ? rand() : -rand();
char *str = int_to_str(n, "0123456789");
if (str != NULL) {
printf("%d == %s\n", n, str);
free(str);
} else {
perror("int_to_str()");
}
}
}

How to remove the character at a given index from a string in C?

How do I remove a character from a string?
If I have the string "abcdef" and I want to remove "b" how do I do that?
Removing the first character is easy with this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[] = "abcdef";
char word2[10];
strcpy(word2, &word[1]);
printf("%s\n", word2);
return 0;
}
and
strncpy(word2, word, strlen(word) - 1);
will give me the string without the last character, but I still didn't figure out how to remove a char in the middle of a string.
memmove can handle overlapping areas, I would try something like that (not tested, maybe +-1 issue)
char word[] = "abcdef";
int idxToDel = 2;
memmove(&word[idxToDel], &word[idxToDel + 1], strlen(word) - idxToDel);
Before: "abcdef"
After: "abdef"
Try this :
void removeChar(char *str, char garbage) {
char *src, *dst;
for (src = dst = str; *src != '\0'; src++) {
*dst = *src;
if (*dst != garbage) dst++;
}
*dst = '\0';
}
Test program:
int main(void) {
char* str = malloc(strlen("abcdef")+1);
strcpy(str, "abcdef");
removeChar(str, 'b');
printf("%s", str);
free(str);
return 0;
}
Result:
>>acdef
My way to remove all specified chars:
void RemoveChars(char *s, char c)
{
int writer = 0, reader = 0;
while (s[reader])
{
if (s[reader]!=c)
{
s[writer++] = s[reader];
}
reader++;
}
s[writer]=0;
}
char a[]="string";
int toBeRemoved=2;
memmove(&a[toBeRemoved],&a[toBeRemoved+1],strlen(a)-toBeRemoved);
puts(a);
Try this . memmove will overlap it.
Tested.
Really surprised this hasn't been posted before.
strcpy(&str[idx_to_delete], &str[idx_to_delete + 1]);
Pretty efficient and simple. strcpy uses memmove on most implementations.
int chartoremove = 1;
strncpy(word2, word, chartoremove);
strncpy(((char*)word2)+chartoremove, ((char*)word)+chartoremove+1,
strlen(word)-1-chartoremove);
Ugly as hell
The following will extends the problem a bit by removing from the first string argument any character that occurs in the second string argument.
/*
* delete one character from a string
*/
static void
_strdelchr( char *s, size_t i, size_t *a, size_t *b)
{
size_t j;
if( *a == *b)
*a = i - 1;
else
for( j = *b + 1; j < i; j++)
s[++(*a)] = s[j];
*b = i;
}
/*
* delete all occurrences of characters in search from s
* returns nr. of deleted characters
*/
size_t
strdelstr( char *s, const char *search)
{
size_t l = strlen(s);
size_t n = strlen(search);
size_t i;
size_t a = 0;
size_t b = 0;
for( i = 0; i < l; i++)
if( memchr( search, s[i], n))
_strdelchr( s, i, &a, &b);
_strdelchr( s, l, &a, &b);
s[++a] = '\0';
return l - a;
}
This is an example of removing vowels from a string
#include <stdio.h>
#include <string.h>
void lower_str_and_remove_vowel(int sz, char str[])
{
for(int i = 0; i < sz; i++)
{
str[i] = tolower(str[i]);
if(str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u')
{
for(int j = i; j < sz; j++)
{
str[j] = str[j + 1];
}
sz--;
i--;
}
}
}
int main(void)
{
char str[101];
gets(str);
int sz = strlen(str);// size of string
lower_str_and_remove_vowel(sz, str);
puts(str);
}
Input:
tour
Output:
tr
Use strcat() to concatenate strings.
But strcat() doesn't allow overlapping so you'd need to create a new string to hold the output.
I tried with strncpy() and snprintf().
int ridx = 1;
strncpy(word2,word,ridx);
snprintf(word2+ridx,10-ridx,"%s",&word[ridx+1]);
Another solution, using memmove() along with index() and sizeof():
char buf[100] = "abcdef";
char remove = 'b';
char* c;
if ((c = index(buf, remove)) != NULL) {
size_t len_left = sizeof(buf) - (c+1-buf);
memmove(c, c+1, len_left);
}
buf[] now contains "acdef"
This might be one of the fastest ones, if you pass the index:
void removeChar(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
This code will delete all characters that you enter from string
#include <stdio.h>
#include <string.h>
#define SIZE 1000
char *erase_c(char *p, int ch)
{
char *ptr;
while (ptr = strchr(p, ch))
strcpy(ptr, ptr + 1);
return p;
}
int main()
{
char str[SIZE];
int ch;
printf("Enter a string\n");
gets(str);
printf("Enter the character to delete\n");
ch = getchar();
erase_c(str, ch);
puts(str);
return 0;
}
input
a man, a plan, a canal Panama
output
A mn, pln, cnl, Pnm!
Edit : Updated the code zstring_remove_chr() according to the latest version of the library.
From a BSD licensed string processing library for C, called zString
https://github.com/fnoyanisi/zString
Function to remove a character
int zstring_search_chr(char *token,char s){
if (!token || s=='\0')
return 0;
for (;*token; token++)
if (*token == s)
return 1;
return 0;
}
char *zstring_remove_chr(char *str,const char *bad) {
char *src = str , *dst = str;
/* validate input */
if (!(str && bad))
return NULL;
while(*src)
if(zstring_search_chr(bad,*src))
src++;
else
*dst++ = *src++; /* assign first, then incement */
*dst='\0';
return str;
}
Exmaple Usage
char s[]="this is a trial string to test the function.";
char *d=" .";
printf("%s\n",zstring_remove_chr(s,d));
Example Output
thisisatrialstringtotestthefunction
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
void dele_char(char s[],char ch)
{
int i,j;
for(i=0;s[i]!='\0';i++)
{
if(s[i]==ch)
{
for(j=i;s[j]!='\0';j++)
s[j]=s[j+1];
i--;
}
}
}
int main()
{
char s[MAX],ch;
printf("Enter the string\n");
gets(s);
printf("Enter The char to be deleted\n");
scanf("%c",&ch);
dele_char(s,ch);
printf("After Deletion:= %s\n",s);
return 0;
}
#include <stdio.h>
#include <string.h>
int main(){
char ch[15],ch1[15];
int i;
gets(ch); // the original string
for (i=0;i<strlen(ch);i++){
while (ch[i]==ch[i+1]){
strncpy(ch1,ch,i+1); //ch1 contains all the characters up to and including x
ch1[i]='\0'; //removing x from ch1
strcpy(ch,&ch[i+1]); //(shrinking ch) removing all the characters up to and including x from ch
strcat(ch1,ch); //rejoining both parts
strcpy(ch,ch1); //just wanna stay classy
}
}
puts(ch);
}
Let's suppose that x is the "symbol" of the character you want to remove
,my idea was to divide the string into 2 parts:
1st part will countain all the characters from the index 0 till (and including) the target character x.
2nd part countains all the characters after x (not including x)
Now all you have to do is to rejoin both parts.
This is what you may be looking for while counter is the index.
#include <stdio.h>
int main(){
char str[20];
int i,counter;
gets(str);
scanf("%d", &counter);
for (i= counter+1; str[i]!='\0'; i++){
str[i-1]=str[i];
}
str[i-1]=0;
puts(str);
return 0;
}
I know that the question is very old, but I will leave my implementation here:
char *ft_strdelchr(const char *str,char c)
{
int i;
int j;
char *s;
char *newstr;
i = 0;
j = 0;
// cast to char* to be able to modify, bc the param is const
// you guys can remove this and change the param too
s = (char*)str;
// malloc the new string with the necessary length.
// obs: strcountchr returns int number of c(haracters) inside s(tring)
if (!(newstr = malloc(ft_strlen(s) - ft_strcountchr(s, c) + 1 * sizeof(char))))
return (NULL);
while (s[i])
{
if (s[i] != c)
{
newstr[j] = s[i];
j++;
}
i++;
}
return (newstr);
}
just throw to a new string the characters that are not equal to the character you want to remove.
Following should do it :
#include <stdio.h>
#include <string.h>
int main (int argc, char const* argv[])
{
char word[] = "abcde";
int i;
int len = strlen(word);
int rem = 1;
/* remove rem'th char from word */
for (i = rem; i < len - 1; i++) word[i] = word[i + 1];
if (i < len) word[i] = '\0';
printf("%s\n", word);
return 0;
}
This is a pretty basic way to do it:
void remove_character(char *string, int index) {
for (index; *(string + index) != '\0'; index++) {
*(string + index) = *(string + index + 1);
}
}
I am amazed none of the answers posted in more than 10 years mention this:
copying the string without the last byte with strncpy(word2, word, strlen(word)-1); is incorrect: the null terminator will not be set at word2[strlen(word) - 1]. Furthermore, this code would cause a crash if word is an empty string (which does not have a last character).
The function strncpy is not a good candidate for this problem. As a matter of fact, it is not recommended for any problem because it does not set a null terminator in the destination array if the n argument is less of equal to the source string length.
Here is a simple generic solution to copy a string while removing the character at offset pos, that does not assume pos to be a valid offset inside the string:
#include <stddef.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t i;
for (i = 0; i < pos && src[i] != '\0'; i++) {
dest[i] = src[i];
}
for (; src[i] != '\0'; i++) {
dest[i] = src[i + 1];
}
dest[i] = '\0';
return dest;
}
This function also works if dest == src, but for removing the character in place in a modifiable string, use this more efficient version:
#include <stddef.h>
char *removeat_in_place(char *str, size_t pos) {
size_t i;
for (i = 0; i < pos && str[i] != '\0'; i++)
continue;
for (; str[i] != '\0'; i++)
str[i] = str[i + 1];
return str;
}
Finally, here are solutions using library functions:
#include <string.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t len = strlen(src);
if (pos < len) {
memmove(dest, src, pos);
memmove(dest + pos, src + pos + 1, len - pos);
} else {
memmove(dest, src, len + 1);
}
return dest;
}
char *removeat_in_place(char *str, size_t pos) {
size_t len = strlen(str);
if (pos < len) {
memmove(str + pos, str + pos + 1, len - pos);
}
return str;
}
A convenient, simple and fast way to get rid of \0 is to copy the string without the last char (\0) with the help of strncpy instead of strcpy:
strncpy(newStrg,oldStrg,(strlen(oldStrg)-1));

Resources