replacing "\"" by empty character - c

I need to replace " (ASCII value 34) char by empty character "".
In output, instead of quote i get an "?" question mark character.
I tried to use things like:
mystring[itit] = "";
mystring[itit] = '';
mystring[itit] = "\O";
My code:
strcpy( mystring ,op->data.value.str );
for(itit=0;itit<10;itit++)
{
if(mystring[itit] == 34)
{
mystring[itit] = NULL;
}
}
printf( "%s\n",mystring);
Any ideas how to fix that?
For clarification: the strings in mystring are like:
"hello"
"place "
"school"
all with the quotation marks - I Actually need to remove them and get:
hello
place
school

int removeChar(char *str, char c) {
int i, j;
for(i = 0, j = 0 ; str[i] ; i++){
if( str[i] == c) continue; // skip c do not copy it
str[j] = str[i]; // shift characters left
j++;
}
str[j]=0; // terminate the string
return j; // return the actual size
}

What you need to do is remove the character, not replace it, since you're not replacing it with anything. To do this, when you find the character is question, you need to move the remaining characters down.
int i,j;
strcpy(mystring, "aa\"bb\"cc");
for(i=0,j=0;i<10;i++)
{
if(mystring[i] != '"')
{
mystring[j] = mystring[i];
j++;
}
}
mystring[j] = '\0';
printf("mystring=%s\n",mystring);
Result:
mystring=aabbcc

To remove a character from a string, you can do this:
void remove(char* str, char rm)
{
char *src, *dst;
for (src = dst = str; *src != '\0'; ++src) {
*dst = *src;
if (*dst != rm) ++dst;
}
*dst = '\0'; /*insert terminator at the new place*/
}
and call with rm equal to 34.
This algorithm is well-known; I've adopted it from Kernighan & Ritchie. Do study it carefully with your debugger.

In C, strings are simply arrays of characters with a NUL (0) at the end. (They cannot contain NULs.) As with any array, you can't simply "remove" an element. You need to shift all the following elements one position, with the result that there will be an unneeded element at the end. With strings this extra element isn't a huge problem becauyse the NUL still identifies where the string ends.
In this case, you are copying the string first, so you might as well copy it without the characters you want to delete. Unless you know how many such characters there are, you will need to have allocated enough space in the new string for the entire string you want to copy:
/* Before this, you must ensure that mystring has enough space */
{
char* out = mystring;
const char* in = op->data.value.str;
do {
if (*in != '"') *out++ = *in;
} while (*in++);
}
Note: I use the fact that strings are NUL-terminated to terminate the loop, which saves me from having to know in advance how long op->data.value.str is. For this reason, I use character pointers rather than indexes.

There is no "empty character". A string can be empty by having no characters, but a character is an atomic element and can't be empty, like a box of apples can be empty, but one can't have an "empty apple".
Instead, you need to remove the quotes and close the space they took up. Better yet, if you do the copying yourself, just don't copy them:
char *psrc = op->data.value.str;
char *pdest = mystring;
while (*psrc != '\0')
{
if (*psrc != '\"')
{
*pdest = *psrc;
++pdest;
}
++psrc;
}
*pdest = '\0';

You can use this to strip all '\"'-characters:
void stripquotes(char *ptr) {
char *ptr2 = ptr;
do {
*ptr2 = *ptr++;
if (*ptr2 != '\"')
ptr2++;
} while (*ptr);
}

Related

Cannot assign chars from one string to another

So I have a function that takes a string, and strips out special format characters, and assigns it to another string for later processing.
A sample call would be:
act_new("$t does $d");
It should strip out the $t and the $d and leave the second string as " does ", but its not assigning anything. I am getting back into programming after quite a few years of inactivity, and this is someone elses code (A MUD codebase, Rom), but I feel like I am missing something fundamental with pointer assignments. Any tips?
(This is truncated code, the rest has no operations on str or point until much later)
void act_new(const char *format)
{
const char *str;
char *point;
str = format;
while ( *str != '\0' ) {
if ( *str != '$' ) {
*point++ = *str++;
continue;
}
}
}
You need to increment str every time through the loop, not only when you assign to point. Otherwise you end up in an infinite loop when the character doesn't match the if condition.
You also want to skip the character after $, so you have to increment str twice when you encounter $.
The code is simpler if you use a for loop and array indexing rather than pointer arithmetic.
size_t len = strlen(format);
for (size_t i = 0; i < len; i++) {
if (format[i] == '$') {
i++; // extra increment to skip character after $
} else {
*point++ = format[i];
}
}
There are a few problems with your code, as pointed out in the comments:
point is not initialized (garbage pointer value)
continue doesn't do anything
infinite loop if a $ is encountered
When writing the function, one must also keep in mind to skip an extra character if a $ is encountered if and only if it's not the last character in the string (except for the '\0').
Since you know how many times you need to loop, a for loop is better suited and, as a bonus, you don't have to explicitly check if the character after a $ is '\0' when skipping an extra character in format (renamed src below). Also, don't forget to terminate the destination string.
This code will take care of those things for you:
void act_new(const char *src)
{
const size_t length = strlen(src);
char * const dst = (char*)malloc(sizeof(char)*(length+1));
if(dst == NULL)
// Error handling left out
return;
char *point = dst;
for(size_t i = 0; i < length; ++i)
{
if(src[i] == '$')
{
++i;
continue;
}
*point++ = src[i];
}
*point = '\0'; //Terminate string properly
printf("%s\n", dst);
free(dst);
}

String Palindrome function that doesn't work as intended in C [duplicate]

What is the easiest and most efficient way to remove spaces from a string in C?
Easiest and most efficient don't usually go together…
Here's a possible solution for in-place removal:
void remove_spaces(char* s) {
char* d = s;
do {
while (*d == ' ') {
++d;
}
} while (*s++ = *d++);
}
Here's a very compact, but entirely correct version:
do while(isspace(*s)) s++; while(*d++ = *s++);
And here, just for my amusement, are code-golfed versions that aren't entirely correct, and get commenters upset.
If you can risk some undefined behavior, and never have empty strings, you can get rid of the body:
while(*(d+=!isspace(*s++)) = *s);
Heck, if by space you mean just space character:
while(*(d+=*s++!=' ')=*s);
Don't use that in production :)
As we can see from the answers posted, this is surprisingly not a trivial task. When faced with a task like this, it would seem that many programmers choose to throw common sense out the window, in order to produce the most obscure snippet they possibly can come up with.
Things to consider:
You will want to make a copy of the string, with spaces removed. Modifying the passed string is bad practice, it may be a string literal. Also, there are sometimes benefits of treating strings as immutable objects.
You cannot assume that the source string is not empty. It may contain nothing but a single null termination character.
The destination buffer can contain any uninitialized garbage when the function is called. Checking it for null termination doesn't make any sense.
Source code documentation should state that the destination buffer needs to be large enough to contain the trimmed string. Easiest way to do so is to make it as large as the untrimmed string.
The destination buffer needs to hold a null terminated string with no spaces when the function is done.
Consider if you wish to remove all white space characters or just spaces ' '.
C programming isn't a competition over who can squeeze in as many operators on a single line as possible. It is rather the opposite, a good C program contains readable code (always the single-most important quality) without sacrificing program efficiency (somewhat important).
For this reason, you get no bonus points for hiding the insertion of null termination of the destination string, by letting it be part of the copying code. Instead, make the null termination insertion explicit, to show that you haven't just managed to get it right by accident.
What I would do:
void remove_spaces (char* restrict str_trimmed, const char* restrict str_untrimmed)
{
while (*str_untrimmed != '\0')
{
if(!isspace(*str_untrimmed))
{
*str_trimmed = *str_untrimmed;
str_trimmed++;
}
str_untrimmed++;
}
*str_trimmed = '\0';
}
In this code, the source string "str_untrimmed" is left untouched, which is guaranteed by using proper const correctness. It does not crash if the source string contains nothing but a null termination. It always null terminates the destination string.
Memory allocation is left to the caller. The algorithm should only focus on doing its intended work. It removes all white spaces.
There are no subtle tricks in the code. It does not try to squeeze in as many operators as possible on a single line. It will make a very poor candidate for the IOCCC. Yet it will yield pretty much the same machine code as the more obscure one-liner versions.
When copying something, you can however optimize a bit by declaring both pointers as restrict, which is a contract between the programmer and the compiler, where the programmer guarantees that the destination and source are not the same address. This allows more efficient optimization, since the compiler can then copy straight from source to destination without temporary memory in between.
In C, you can replace some strings in-place, for example a string returned by strdup():
char *str = strdup(" a b c ");
char *write = str, *read = str;
do {
if (*read != ' ')
*write++ = *read;
} while (*read++);
printf("%s\n", str);
Other strings are read-only, for example those declared in-code. You'd have to copy those to a newly allocated area of memory and fill the copy by skipping the spaces:
char *oldstr = " a b c ";
char *newstr = malloc(strlen(oldstr)+1);
char *np = newstr, *op = oldstr;
do {
if (*op != ' ')
*np++ = *op;
} while (*op++);
printf("%s\n", newstr);
You can see why people invented other languages ;)
#include <ctype>
char * remove_spaces(char * source, char * target)
{
while(*source++ && *target)
{
if (!isspace(*source))
*target++ = *source;
}
return target;
}
Notes;
This doesn't handle Unicode.
if you are still interested, this function removes spaces from the beginning of the string, and I just had it working in my code:
void removeSpaces(char *str1)
{
char *str2;
str2=str1;
while (*str2==' ') str2++;
if (str2!=str1) memmove(str1,str2,strlen(str2)+1);
}
#include<stdio.h>
#include<string.h>
main()
{
int i=0,n;
int j=0;
char str[]=" Nar ayan singh ";
char *ptr,*ptr1;
printf("sizeof str:%ld\n",strlen(str));
while(str[i]==' ')
{
memcpy (str,str+1,strlen(str)+1);
}
printf("sizeof str:%ld\n",strlen(str));
n=strlen(str);
while(str[n]==' ' || str[n]=='\0')
n--;
str[n+1]='\0';
printf("str:%s ",str);
printf("sizeof str:%ld\n",strlen(str));
}
The easiest and most efficient way to remove spaces from a string is to simply remove the spaces from the string literal. For example, use your editor to 'find and replace' "hello world" with "helloworld", and presto!
Okay, I know that's not what you meant. Not all strings come from string literals, right? Supposing this string you want spaces removed from doesn't come from a string literal, we need to consider the source and destination of your string... We need to consider your entire algorithm, what actual problem you're trying to solve, in order to suggest the simplest and most optimal methods.
Perhaps your string comes from a file (e.g. stdin) and is bound to be written to another file (e.g. stdout). If that's the case, I would question why it ever needs to become a string in the first place. Just treat it as though it's a stream of characters, discarding the spaces as you come across them...
#include <stdio.h>
int main(void) {
for (;;) {
int c = getchar();
if (c == EOF) { break; }
if (c == ' ') { continue; }
putchar(c);
}
}
By eliminating the need for storage of a string, not only does the entire program become much, much shorter, but theoretically also much more efficient.
/* Function to remove all spaces from a given string.
https://www.geeksforgeeks.org/remove-spaces-from-a-given-string/
*/
void remove_spaces(char *str)
{
int count = 0;
for (int i = 0; str[i]; i++)
if (str[i] != ' ')
str[count++] = str[i];
str[count] = '\0';
}
Code taken from zString library
/* search for character 's' */
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;
}
Code example
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
Have a llok at the zString code, you may find it useful
https://github.com/fnoyanisi/zString
That's the easiest I could think of (TESTED) and it works!!
char message[50];
fgets(message, 50, stdin);
for( i = 0, j = 0; i < strlen(message); i++){
message[i-j] = message[i];
if(message[i] == ' ')
j++;
}
message[i] = '\0';
Here is the simplest thing i could think of. Note that this program uses second command line argument (argv[1]) as a line to delete whitespaces from.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*The function itself with debug printing to help you trace through it.*/
char* trim(const char* str)
{
char* res = malloc(sizeof(str) + 1);
char* copy = malloc(sizeof(str) + 1);
copy = strncpy(copy, str, strlen(str) + 1);
int index = 0;
for (int i = 0; i < strlen(copy) + 1; i++) {
if (copy[i] != ' ')
{
res[index] = copy[i];
index++;
}
printf("End of iteration %d\n", i);
printf("Here is the initial line: %s\n", copy);
printf("Here is the resulting line: %s\n", res);
printf("\n");
}
return res;
}
int main(int argc, char* argv[])
{
//trim function test
const char* line = argv[1];
printf("Here is the line: %s\n", line);
char* res = malloc(sizeof(line) + 1);
res = trim(line);
printf("\nAnd here is the formatted line: %s\n", res);
return 0;
}
This is implemented in micro controller and it works, it should avoid all problems and it is not a smart way of doing it, but it will work :)
void REMOVE_SYMBOL(char* string, uint8_t symbol)
{
uint32_t size = LENGHT(string); // simple string length function, made my own, since original does not work with string of size 1
uint32_t i = 0;
uint32_t k = 0;
uint32_t loop_protection = size*size; // never goes into loop that is unbrakable
while(i<size)
{
if(string[i]==symbol)
{
k = i;
while(k<size)
{
string[k]=string[k+1];
k++;
}
}
if(string[i]!=symbol)
{
i++;
}
loop_protection--;
if(loop_protection==0)
{
i = size;
break;
}
}
}
While this is not as concise as the other answers, it is very straightforward to understand for someone new to C, adapted from the Calculix source code.
char* remove_spaces(char * buff, int len)
{
int i=-1,k=0;
while(1){
i++;
if((buff[i]=='\0')||(buff[i]=='\n')||(buff[i]=='\r')||(i==len)) break;
if((buff[i]==' ')||(buff[i]=='\t')) continue;
buff[k]=buff[i];
k++;
}
buff[k]='\0';
return buff;
}
I assume the C string is in a fixed memory, so if you replace spaces you have to shift all characters.
The easiest seems to be to create new string and iterate over the original one and copy only non space characters.
I came across a variation to this question where you need to reduce multiply spaces into one space "represent" the spaces.
This is my solution:
char str[] = "Put Your string Here.....";
int copyFrom = 0, copyTo = 0;
printf("Start String %s\n", str);
while (str[copyTo] != 0) {
if (str[copyFrom] == ' ') {
str[copyTo] = str[copyFrom];
copyFrom++;
copyTo++;
while ((str[copyFrom] == ' ') && (str[copyFrom] !='\0')) {
copyFrom++;
}
}
str[copyTo] = str[copyFrom];
if (str[copyTo] != '\0') {
copyFrom++;
copyTo++;
}
}
printf("Final String %s\n", str);
Hope it helps :-)

Selective removal of specific char in a string

Suppose I have a string that may look something like this:
"value" "some other value" "other value" "some value"
My goal is to remove the blanks selectively, like so:
"value""some other value""other value""some value"
such that the blanks remain only inside strings contained in quotes:
"some other value"
I have the following function:
void rmChar(char *str, char c)
{
char *src, *dest;
src = dest = str;
while(*src != '\0')
{
if (*src != c)
{
*dest = *src;
dest++;
}
src++;
}
*dest = '\0';
}
which removes all occurrences of char c in str and I though I should use some more conditional expressions to do the removal only when certain things happen.
Got any clues?
I just thought of doing this. Below is my program.
Note: This may not be an efficient program (bad time or space complexity), however it does what you are trying to do (if I understood your question right).
Note Also I have used malloc() in this code. You would not use it if you were changing the contents of the original string without using any other string. But as I understood from your question you were making a NEW string which contained the value of original string after removing the spaces.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void rmChar(char *,char, int );
int main()
{
char string[200] = "\"This is a value\" \"and another value\" \"value2 this\"";
char c;
c = '"';
printf("%s\n",string);
int len = strlen(string);
/*Pass the address of the stringi, char c, and the length of the string*/
/*Length of the string will be required for malloc() inside function rmChar()*/
rmChar(string, c, len);
return 0;
}
void rmChar(char *str,char c, int len)
{
char *dest1, *dest2;
char *src = str;
int removeFlag = 0; /* You will remove all the spaces ' ' that come after removeFlag is odd*/
dest1 = malloc(len);
dest2 = dest1;
while(*str != '\0')
{
if(*str == c)
{
removeFlag++;
if (removeFlag %2 == 0)
{
/* This is required because every 2nd time you get a " removeFlag is increased so next if is NOT true*/
*dest2 = *str;
dest2++;
}
}
if ((removeFlag % 2) == 1)
{
*dest2 = *str;
dest2++;
}
str++;
}
*dest2 = '\0';
printf("%s\n", dest1);
/* If you want to copy the string without spaces to the original string uncomment below line*/
//strcpy(src, dest1);
free(dest1);
}
You needed one more variable to use as some kind of flag which indicated after which " you need to remove spaces. Then you would use that flag in a if() statement in some way. Here int removeFlag is the flag I have used.
The loop that iterates over the string has to keep track if it is currently looking at a character inside a quoted string or not, and then use that information to only delete when appropriate.
To keep track of that information you could use an additional variable that gets updated every time there is a ".
int quoted = 0;
while (...) {
if (*src == '"') {
// set `quoted` to 1 or 0, as appropriate
...
}
// delete only if !quoted
...
}

What is wrong with this code?

As you can see below I have created a little program to concatenate 2 strings using C, as you may imagine this code doesn't work, I have already corrected it myself by using Array notation instead of pointers, and it works just fine, however I'm still not sure why is it that my code fails being almost a replica of my corrected code.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void concatena(char *str1, char *str2){
char *strAux;
int mover;
mover = 0;
strAux = (char *)(malloc(strlen(str1) + strlen(str2)+2));
*(strAux) = '\0';
if(str1 == '\0')
*strAux = '\0';
else
while(str1 != '\0'){
*(strAux+mover++)=*(str1++);
}
if(str2 == '\0')
*strAux = '\0';
else
while(str2 != '\0'){
*(strAux+mover++)=*(str2++);
}
strAux='\0';
str1=strAux;
printf("%s", str1);
free(strAux);
}
I´m still a C beginner (And yes, I'm aware that there are libraries like string.h, I'm asking this for academic reasons) and I have been told that char pointers and arrays are the same thing, something that confuses the heck out of me.
Any help is greatly appreciated.
The first problem I see is with this section:
if(str2 == '\0')
*strAux = '\0';
Just before this code, you've filled up strAux with the string from str1.
Then, if str2 is empty, you suddenly put a null-terminator at the beginning of strAux, eliminating all the work you've done so far!
I think what you intend is:
if(*str2 == '\0')
*(strAux+mover) = '\0';
Its the same thing again after your loop for str2, you have the code:
strAux='\0';
Again, this puts a null-terminator at the start of strAux, effectively ending the newly created string before it even gets started.
Here's how I'd re-write your code:
void concatena(char *str1, char *str2){
char *strAux;
int mover = 0;
strAux = (char *)(malloc(strlen(str1) + strlen(str2)+1)); // Changed to +1, NOT +2
*(strAux) = '\0'; // Start the string as (empty)
while(*str1 != '\0'){ // Copy the first string over.
*(strAux+mover++)=*(str1++);
}
while(*str2 != '\0'){ // Copy the second string over.
*(strAux+mover++)=*(str2++);
}
*(strAux+mover)='\0'; // End the new, combined string.
printf("%s", strAux); // Show the results.
free(strAux);
}
Accepting the same constraints, here is how I would (re)write your code. Unfortunately there is a specification shortcoming: should the concatenation occur to the first string passed? Or should a new string be created? Here are both methods:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *concatena (const char *str1, const char *str2)
{
char *op, *newStr = (char*)malloc (strlen (str1) + strlen (str2) + 1);
if (!newStr)
{
fprintf (stderr, "concatena: error allocating\n");
return;
}
op = newStr; // set up output pointer
while (str1 && *str1) // copy first string
*op++ = *str1++;
while (str2 && *str2) // concatenate second string
*op++ = *str2++;
*op = '\000'; // add conventional NUL termination
return newStr;
}
void concatenb (char *str1, const char *str2)
{
char *op;
if (!str1)
{
fprintf (stderr, "concatenb: NULL string 1\n");
return;
}
op = &str1 [strlen (str1)]; // set output pointer at trailing NUL
while (str2 && *str2) // concatenate second string
*op++ = *str2++;
*op = '\000'; // add conventional NUL termination
}
strAux = (char *)(malloc(strlen(str1) + strlen(str2)+2));
2 is not required, just 1 is sufficient for the termination character.
*(strAux) = '\0';
This should be happening only at the end of all your computation. Not in between the concatenation i.e.,
while(*str1 != '\0'){ // This loops copies the first string
// ^ Notice that you need to dereference to check for the termination character.
*(strAux+mover++)=*(str1++);
}
while(*str2 != '\0'){ // This loop copies the second string
*(strAux+mover++)=*(str2++);
}
// Finally adding termination character
*(strAux+mover) = '\0'; // since with mover you are keeping track of locations.
The amount of errors in your code is disheartening. You should probably pick up a good C book and start over.
First off, there's a library function that you can use to concatenate strings:
const unsigned int len = strlen(str1) + strlen(str2) + 1;
char * dst = malloc(len);
strncat(dst, str1, len);
strncat(dst, str2, len);
Now, if you insist on doing it manually, you have to get pointers and dereferencing right:
char * d = dst;
while (*str1 != 0) *dst++ = *str1++;
while (*str2 != 0) *dst++ = *str2++;
*dst = 0;
// d now points to the beginning of the concatenated string
The two loops check if the current character in the input string is nonzero, and if so, then they copy that character to the current character in the output string, and then both input and output pointer are advanced. (This is all done in one wash by use of the postfix ++ operator.) Finally, the last character is set to zero to create a new null-terminator.
In the process we modified all three pointers dst, str1 and str2. The latter two came in as input function arguments by copy, so that's fine. For returning the concatenated string we made a copy of dst before the loop, which we can return in the end.

Remove spaces from a string in C

What is the easiest and most efficient way to remove spaces from a string in C?
Easiest and most efficient don't usually go together…
Here's a possible solution for in-place removal:
void remove_spaces(char* s) {
char* d = s;
do {
while (*d == ' ') {
++d;
}
} while (*s++ = *d++);
}
Here's a very compact, but entirely correct version:
do while(isspace(*s)) s++; while(*d++ = *s++);
And here, just for my amusement, are code-golfed versions that aren't entirely correct, and get commenters upset.
If you can risk some undefined behavior, and never have empty strings, you can get rid of the body:
while(*(d+=!isspace(*s++)) = *s);
Heck, if by space you mean just space character:
while(*(d+=*s++!=' ')=*s);
Don't use that in production :)
As we can see from the answers posted, this is surprisingly not a trivial task. When faced with a task like this, it would seem that many programmers choose to throw common sense out the window, in order to produce the most obscure snippet they possibly can come up with.
Things to consider:
You will want to make a copy of the string, with spaces removed. Modifying the passed string is bad practice, it may be a string literal. Also, there are sometimes benefits of treating strings as immutable objects.
You cannot assume that the source string is not empty. It may contain nothing but a single null termination character.
The destination buffer can contain any uninitialized garbage when the function is called. Checking it for null termination doesn't make any sense.
Source code documentation should state that the destination buffer needs to be large enough to contain the trimmed string. Easiest way to do so is to make it as large as the untrimmed string.
The destination buffer needs to hold a null terminated string with no spaces when the function is done.
Consider if you wish to remove all white space characters or just spaces ' '.
C programming isn't a competition over who can squeeze in as many operators on a single line as possible. It is rather the opposite, a good C program contains readable code (always the single-most important quality) without sacrificing program efficiency (somewhat important).
For this reason, you get no bonus points for hiding the insertion of null termination of the destination string, by letting it be part of the copying code. Instead, make the null termination insertion explicit, to show that you haven't just managed to get it right by accident.
What I would do:
void remove_spaces (char* restrict str_trimmed, const char* restrict str_untrimmed)
{
while (*str_untrimmed != '\0')
{
if(!isspace(*str_untrimmed))
{
*str_trimmed = *str_untrimmed;
str_trimmed++;
}
str_untrimmed++;
}
*str_trimmed = '\0';
}
In this code, the source string "str_untrimmed" is left untouched, which is guaranteed by using proper const correctness. It does not crash if the source string contains nothing but a null termination. It always null terminates the destination string.
Memory allocation is left to the caller. The algorithm should only focus on doing its intended work. It removes all white spaces.
There are no subtle tricks in the code. It does not try to squeeze in as many operators as possible on a single line. It will make a very poor candidate for the IOCCC. Yet it will yield pretty much the same machine code as the more obscure one-liner versions.
When copying something, you can however optimize a bit by declaring both pointers as restrict, which is a contract between the programmer and the compiler, where the programmer guarantees that the destination and source are not the same address. This allows more efficient optimization, since the compiler can then copy straight from source to destination without temporary memory in between.
In C, you can replace some strings in-place, for example a string returned by strdup():
char *str = strdup(" a b c ");
char *write = str, *read = str;
do {
if (*read != ' ')
*write++ = *read;
} while (*read++);
printf("%s\n", str);
Other strings are read-only, for example those declared in-code. You'd have to copy those to a newly allocated area of memory and fill the copy by skipping the spaces:
char *oldstr = " a b c ";
char *newstr = malloc(strlen(oldstr)+1);
char *np = newstr, *op = oldstr;
do {
if (*op != ' ')
*np++ = *op;
} while (*op++);
printf("%s\n", newstr);
You can see why people invented other languages ;)
#include <ctype>
char * remove_spaces(char * source, char * target)
{
while(*source++ && *target)
{
if (!isspace(*source))
*target++ = *source;
}
return target;
}
Notes;
This doesn't handle Unicode.
if you are still interested, this function removes spaces from the beginning of the string, and I just had it working in my code:
void removeSpaces(char *str1)
{
char *str2;
str2=str1;
while (*str2==' ') str2++;
if (str2!=str1) memmove(str1,str2,strlen(str2)+1);
}
#include<stdio.h>
#include<string.h>
main()
{
int i=0,n;
int j=0;
char str[]=" Nar ayan singh ";
char *ptr,*ptr1;
printf("sizeof str:%ld\n",strlen(str));
while(str[i]==' ')
{
memcpy (str,str+1,strlen(str)+1);
}
printf("sizeof str:%ld\n",strlen(str));
n=strlen(str);
while(str[n]==' ' || str[n]=='\0')
n--;
str[n+1]='\0';
printf("str:%s ",str);
printf("sizeof str:%ld\n",strlen(str));
}
The easiest and most efficient way to remove spaces from a string is to simply remove the spaces from the string literal. For example, use your editor to 'find and replace' "hello world" with "helloworld", and presto!
Okay, I know that's not what you meant. Not all strings come from string literals, right? Supposing this string you want spaces removed from doesn't come from a string literal, we need to consider the source and destination of your string... We need to consider your entire algorithm, what actual problem you're trying to solve, in order to suggest the simplest and most optimal methods.
Perhaps your string comes from a file (e.g. stdin) and is bound to be written to another file (e.g. stdout). If that's the case, I would question why it ever needs to become a string in the first place. Just treat it as though it's a stream of characters, discarding the spaces as you come across them...
#include <stdio.h>
int main(void) {
for (;;) {
int c = getchar();
if (c == EOF) { break; }
if (c == ' ') { continue; }
putchar(c);
}
}
By eliminating the need for storage of a string, not only does the entire program become much, much shorter, but theoretically also much more efficient.
/* Function to remove all spaces from a given string.
https://www.geeksforgeeks.org/remove-spaces-from-a-given-string/
*/
void remove_spaces(char *str)
{
int count = 0;
for (int i = 0; str[i]; i++)
if (str[i] != ' ')
str[count++] = str[i];
str[count] = '\0';
}
Code taken from zString library
/* search for character 's' */
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;
}
Code example
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
Have a llok at the zString code, you may find it useful
https://github.com/fnoyanisi/zString
That's the easiest I could think of (TESTED) and it works!!
char message[50];
fgets(message, 50, stdin);
for( i = 0, j = 0; i < strlen(message); i++){
message[i-j] = message[i];
if(message[i] == ' ')
j++;
}
message[i] = '\0';
Here is the simplest thing i could think of. Note that this program uses second command line argument (argv[1]) as a line to delete whitespaces from.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*The function itself with debug printing to help you trace through it.*/
char* trim(const char* str)
{
char* res = malloc(sizeof(str) + 1);
char* copy = malloc(sizeof(str) + 1);
copy = strncpy(copy, str, strlen(str) + 1);
int index = 0;
for (int i = 0; i < strlen(copy) + 1; i++) {
if (copy[i] != ' ')
{
res[index] = copy[i];
index++;
}
printf("End of iteration %d\n", i);
printf("Here is the initial line: %s\n", copy);
printf("Here is the resulting line: %s\n", res);
printf("\n");
}
return res;
}
int main(int argc, char* argv[])
{
//trim function test
const char* line = argv[1];
printf("Here is the line: %s\n", line);
char* res = malloc(sizeof(line) + 1);
res = trim(line);
printf("\nAnd here is the formatted line: %s\n", res);
return 0;
}
This is implemented in micro controller and it works, it should avoid all problems and it is not a smart way of doing it, but it will work :)
void REMOVE_SYMBOL(char* string, uint8_t symbol)
{
uint32_t size = LENGHT(string); // simple string length function, made my own, since original does not work with string of size 1
uint32_t i = 0;
uint32_t k = 0;
uint32_t loop_protection = size*size; // never goes into loop that is unbrakable
while(i<size)
{
if(string[i]==symbol)
{
k = i;
while(k<size)
{
string[k]=string[k+1];
k++;
}
}
if(string[i]!=symbol)
{
i++;
}
loop_protection--;
if(loop_protection==0)
{
i = size;
break;
}
}
}
While this is not as concise as the other answers, it is very straightforward to understand for someone new to C, adapted from the Calculix source code.
char* remove_spaces(char * buff, int len)
{
int i=-1,k=0;
while(1){
i++;
if((buff[i]=='\0')||(buff[i]=='\n')||(buff[i]=='\r')||(i==len)) break;
if((buff[i]==' ')||(buff[i]=='\t')) continue;
buff[k]=buff[i];
k++;
}
buff[k]='\0';
return buff;
}
I assume the C string is in a fixed memory, so if you replace spaces you have to shift all characters.
The easiest seems to be to create new string and iterate over the original one and copy only non space characters.
I came across a variation to this question where you need to reduce multiply spaces into one space "represent" the spaces.
This is my solution:
char str[] = "Put Your string Here.....";
int copyFrom = 0, copyTo = 0;
printf("Start String %s\n", str);
while (str[copyTo] != 0) {
if (str[copyFrom] == ' ') {
str[copyTo] = str[copyFrom];
copyFrom++;
copyTo++;
while ((str[copyFrom] == ' ') && (str[copyFrom] !='\0')) {
copyFrom++;
}
}
str[copyTo] = str[copyFrom];
if (str[copyTo] != '\0') {
copyFrom++;
copyTo++;
}
}
printf("Final String %s\n", str);
Hope it helps :-)

Resources