I'm new to C and have started learning about strings. I want to create a function called
void SpaceRemover(char *input )
It should remove the spaced from a given string array that has lots of space
The code that I've produced so far removes all the spaces and doesn't provide the output I'm looking for. Can anyone help me with this?
char* SpaceRemover(char *input){
char *output=input;
for (int i = 0, j = 0; i<strlen(input); i++,j++)
{
if (input[i]!=' ')
output[j]=input[i];
else
j--;
}
return output;
}
I made this but I know its wrong and does not do what i want it to but honestly this is all i could this of -_-
You could just do as below
void SpaceRemover(char *name)
{
int i=0,j=0;
for (i = 0;i<strlen(name);i++)
{
if (name[i] != ' ' || (name[i] == ' ' && name[i+1] != ' ' && j!= 0))
{
name[j++] = name[i];
}
}
name[j]='\0'; //Terminate the string to avoid junk chars
}
Where
if (name[i] != ' ' || (name[i] == ' ' && name[i+1] != ' ' && j != 0))
will let you copy only if current char is not space or current char is space and next char is not space(to include single space apart in the beginning).
Also don't forget to terminate the string.
name[j]='\0';
The problem is that you remove all spaces.
char *SpaceRemover(char *name){
char *output = name;
int j = 0;
for (int i = 0; i < strlen(name); i++) {
if (name[i] != ' ' || (name[i] == ' ' && name[i + 1] != ' ') {
output[j] = name[i];
j += 1;
}
}
output[j] = '\0'
return output;
}
This condition should let one space through.
You might notice I replaced the void return type with a char * so t o use the function you will need to use:
name = SpaceRemover(name);
I would be using a flag to activate when a space is met.
This might need to be tweaked if you want to remove leading and trailing spaces too.
A space will be added to output and the flag will be used to avoid the next ones to be added. The flag will be deactivated when something else than a space is met.
As stated Alex in comments, decrementing j in loop while it's incremented in the for statement isn't recommended.
I would copy each characters in the for loop instead of filtering a pre-copied output.
char space_found = 0;
char *output = malloc(sizeof(char) * (strlen(name) + 1));
int j = 0;
for (int i = 0; i < strlen(name); ++i)
{
if (name[i] == ' ' and space_found == 0)
{
space_found = 1;
output[j++] = name[i];
}
if (name[i] != ' ')
{
space_found = 0;
output[j++] = name[i];
}
}
output[j] = '\0';
void spaceRemover(char* str)
{
char temp[50] = {0};
int j = 0;
strncpy(temp, str, strlen(str) + 1);
for(int i = 0; i < strlen(str); i++)
{
if(temp[i] != ' ')
{
str[j] = temp[i];
j++;
}
}
str[j] = 0;
}
if you have any questions, feel free to ask, Good Luck
#include <stdio.h>
char *rem(char *str)
{
char *cur=str;
char *nex=str;
while(*nex)
{
if(*nex == ' ') nex++;
else *cur++ = *nex++;
}
*cur=0;
return str;
}
int main(void) {
char z[]=" etc def etc def ";
printf("%s\n", rem(z));
return 0;
}
Related
I need to replace " " (space) with ", " (comma and space).
I have function which receive string as char* and after replacing all this characters prints string on screen.
char* PrintComma(char* Text) {
for (int i = 0; i < strlen(Text); i++) {
if (Text[i] == ' ') {
Text[i] = ',';
}
}
return Text;
}
This replaces " " with "," but I need ", ". I'm not allowed to use a second string or array for saving temp data. I can use only this one string.
Example:
Input => "Hello world my name is"
Output => "Hello, world, my, name, is"
This problem seems like a perfect setup for memmove() which is a library function that copies bytes between two strings but handles overlapping memory blocks.
memmove(
char_pointer + make_room_at + room_to_make,
char_pointer + make_room_at,
init_size - make_room_at + room_to_make
);
Here is the application using memmove().
char* PrintComma(char* Text) {
for (int i = 0; i < strlen(Text); i++) {
if (Text[i] == ' ') {
memmove(
Text + i + 1,
Text + i,
strlen(Text) - i + 1
);
Text[i++] = ',';
}
}
return Text;
}
Here's a working example. The input buffer must be large enough to store the replaced string, as the requirements state that no new string should be created.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void PrintComma(char* Text)
{
char* str = Text;
size_t c, len = strlen(Text);
for (c = 0; Text[c]; Text[c] == ' ' ? c++ : *Text++);
for (size_t i = 0; i < len + c; i++)
{
if (str[i] == ' ')
{
str[i] = ',';
char last = ' ';
for(size_t u = i + 1; u < len + c; u++)
{
char current = str[u];
str[u] = last;
last = current;
}
i += 2;
}
}
}
int main(void)
{
char tmp[100] = { 0 };
const char* TEST = "Hello world my name is";
memcpy(tmp, TEST, strlen(TEST));
printf("Input: %s\n", tmp);
PrintComma(tmp);
printf("Output: %s\n", tmp);
return 0;
}
Result:
Input: Hello world my name is
Output: Hello, world, my, name, is
Based on your requirements:
I have function which receive string as char* and after replacing all this characters prints string on screen.
I don't think you're looking to replace a space with a comma-space. Instead, I think you want to go through the string and print all the characters. When you encounter a space, you print an extra comma. Here's roughly how to do that:
void PrintComma(char *text)
{
const size_t len = strlen(text); // don't call on every iteration
for(size_t i = 0; i < len; i++)
{
if(text[i] == ' ')
putchar(',');
putchar(text[i]);
}
}
You have two requirements:
1) The spaces must be replaced.
2) You cannot use another char array.
These lead to the assumption that the input char* must have adequate allocated space for all the new ,s.
In that case, this would work.
char *PrintComma(char *Text) {
int numberOfSpaces = 0, orignalLength = strlen(Text);
for (int i = 0; i < strlen(Text); i++) {
if (Text[i] == ' ')
numberOfSpaces++;
}
for (int i = orignalLength - 1, j = orignalLength + numberOfSpaces - 1; i >= 0; i--) {
Text[j] = Text[i];
j--;
if (Text[i] == ' ') {
Text[j] = ',';
j--;
}
}
return Text;
}
I need to tokenize a string from an array, i need just three words and ignore all tabs '\t' and spaces ' '
the array line[] is just a test case.
I debugged mine, the first array (supposed to carry only the first word) got filled by spaces & letters from 3 words, not stopping after the first word when a tab or space is met. BTW my program crashed. i suspect getting out of array bounds maybe.
What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char line[] = " CLOOP LDA buffer,x";
char array1[20] ="";
char array2[20] ="";
char array3[20] ="";
int i = 0;
for( i ; i<strlen(line) ; i++)
{
while ( (line[i] != ' ') && (line[i] != '\t'))
{
if(array1[0] == '\0')
{
int j = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array1[j] = line[i];
i++;
j++;
}
}
if(array2[0] =='\0');
{
int k = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array2[k] = line[i];
i++;
k++;
}
}
if(array3[0] == '\0')
{
int g = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array3[g] = line[i];
i++;
g++;
}
}
}
}
printf("array 1: %s\n array2: %s\n array3: %s\n", array1, array2, array3);
return(0);
}
You are over-complicating things. First of all it is difficult to feed all 3 arrays at the same time. The processing for one token should be completely finished before moving to the other token.
I would propose to "eat" all the white spaces before starting to process a token.
That is done by:
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, line[i]) ) continue;
skip_leading_delimiters = 0;
}
After token is processes you can move to the next token and process it. I tried to preserve your concept and approach as much as I could. The amount of while loops has been reduced to 0 since // skip leading delimiters section takes care of it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int is_delimiter(const char * delimiters, char c) // check for a delimiter
{
char *p = strchr (delimiters, c); // if not NULL c is separator
if (p) return 1; // delimeter
else return 0; // not a delimeter
}
int main()
{
char line[] = " CLOOP LDA buffer,x";
char array1[20];
char array2[20];
char array3[20];
int con1 = 1;
int con2 = 0;
int con3 = 0;
int con1s = 0;
int con2s = 0;
int con3s = 0;
int i = 0;
int j = 0;
int skip_leading_delimiters = 1;
char * delimiters = " \b";
for(i = 0; i < strlen(line); i++)
{
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, line[i]) ) continue;
skip_leading_delimiters = 0;
}
if(con1)
{
if(line[i] != ' ' && line[i] != '\t')
{
array1[j] = line[i];
j++;
array1[j] = 0;
con1s = 1;
}
else
{
if(con1s)
{
con1 = 0;
con2 = 1;
skip_leading_delimiters = 1;
j = 0;
}
continue;
}
}
if(con2)
{
if(line[i] != ' ' && line[i] != '\t')
{
array2[j] = line[i];
j++;
array2[j] = 0;
con2s = 1;
}
else
{
con2 = 0;
con3 = 1;
skip_leading_delimiters = 1;
j = 0;
continue;
}
}
if(con3)
{
if(line[i] != ' ' && line[i] != '\t')
{
array3[j] = line[i];
j++;
array3[j] = 0;
con3s = 1;
}
else
{
con3 = 0;
j = 0;
continue;
}
}
}
printf(" array1: %s\n array2: %s\n array3: %s\n", array1, array2, array3);
return(0);
}
Output:
array1: CLOOP
array2: LDA
array3: buffer,x
I need to split a string where there are spaces (ex string: Hello this is an example string. into an array of words. I'm not sure what I'm missing here, I'm also curious as to what the best way to test this function is. The only library function allowed is malloc.
Any help is appreciated!
#include <stdlib.h>
char **ft_split(char *str) {
int wordlength;
int wordcount;
char **wordbank;
int i;
int current;
current = 0;
wordlength = 0;
//while sentence
while (str[wordlength] != '\0') {
//go till letters
while (str[current] == ' ')
current++;
//go till spaces
wordlength = 0;
while (str[wordlength] != ' ' && str[wordlength] != '\0')
wordlength++;
//make memory for word
wordbank[wordcount] = malloc(sizeof(char) * (wordlength - current + 1));
i = 0;
//fill wordbank current
while (i < wordlength - current) {
wordbank[wordcount][i] = str[current];
i++;
current++;
}
//end word with '\0'
wordbank[wordcount][i] = '\0';
wordcount++;
}
return wordbank;
}
There are multiple problems in your code:
You do not allocate an array for wordbank to point to, dereferencing an uninitialized pointer has undefined behavior.
Your approach to scanning the string is broken: you reset wordlength inside the loop so you keep re-scanning from the beginning of the string.
You should allocate an extra entry in the array for a trailing null pointer to indicate the end of the array to the caller.
Here is a modified version:
#include <stdlib.h>
char **ft_split(const char *str) {
size_t i, j, k, wordcount;
char **wordbank;
// count the number of words:
wordcount = 0;
for (i = 0; str[i]; i++) {
if (str[i] != ' ' && (i == 0 || str[i - 1] == ' ')) {
wordcount++;
}
}
// allocate the word array
wordbank = malloc((wordcount + 1) * sizeof(*wordbank));
if (wordbank) {
for (i = k = 0;;) {
// skip spaces
while (str[i] == ' ')
i++;
// check for end of string
if (str[i] == '\0')
break;
// scan for end of word
for (j = i++; str[i] != '\0' && str[i] != ' '; i++)
continue;
// allocate space for word copy
wordbank[k] = p = malloc(i - j + 1);
if (p == NULL) {
// allocation failed: free and return NULL
while (k-- > 0) {
free(wordbank[k]);
}
free(wordbank);
return NULL;
}
// copy string contents
memcpy(p, str + j, i - j);
p[i - j] = '\0';
}
// set a null pointer at the end of the array
wordbank[k] = NULL;
}
return wordbank;
}
You need to malloc() wordbank too. You can count the number for words, and then
wordbank = malloc((count + 1) * sizeof(*wordbank));
if (wordbank == NULL)
return NULL;
Note: sizeof(char) is 1 by definition. And sizeof *pointer is always what you want.
I have this string: print "Foo cakes are yum"
I need to somehow strip all extra whitespace but leave text between quotes alone. This is what i have so far:
char* clean_strip(char* string)
{
int d = 0, c = 0;
char* newstr;
while(string[c] != '\0'){
if(string[c] == ' '){
int temp = c + 1;
if(string[temp] != '\0'){
while(string[temp] == ' ' && string[temp] != '\0'){
if(string[temp] == ' '){
c++;
}
temp++;
}
}
}
newstr[d] = string[c];
c++;
d++;
}
return newstr;
}
This returns this string: print "Foo cakes are yum"
I need to be able to skip text between thw quotes so i get this: print "Foo cakes are yum".
Here is the same question but for php, i need a c answer: Remove spaces in string, excluding these in specified between specified characters
Please help.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* clean_strip(char* string)
{
int d = 0, c = 0;
char* newstr = malloc(strlen(string)+1);
int quoted = 0;
while(string[c] != '\0'){
if (string[c] == '"') quoted = !quoted;
if(!quoted && string[c] == ' '){
int temp = c + 1;
if(string[temp] != '\0'){
while(string[temp] == ' ' && string[temp] != '\0'){
if(string[temp] == ' '){
c++;
}
temp++;
}
}
}
newstr[d] = string[c];
c++;
d++;
}
newstr[d] = 0;
return newstr;
}
int main(int argc, char *argv[])
{
char *input = "print \"Foo cakes are yum\"";
char *output = clean_strip(input);
printf(output);
free(output);
return 0;
}
This will produce the output:
print "Foo cakes are yum"
It works by looking for the " character. If it's found it toggles the variable quoted. If quoted is true, then the whitespace removal is skipped.
Also, your original function never allocates memory for newstr. I added the newstr = malloc(...) part. It is important to allocate memory for strings before writing to them.
I simplified your logic a little.
int main(void)
{
char string[] = "print \"Foo cakes are yum\"";
int i = 0, j = 1, quoted=0;
if (string[0] == '"')
{
quoted=1;
}
for(i=1; i< strlen(string); i++)
{
if (string[i] == '"')
{
quoted = 1-quoted;
}
string[j] = string[i];
if (string[j-1]==' ' && string[j] ==' ' && !quoted)
{
;
}
else
{
j++;
}
}
string[j]='\0';
printf("%s\n",string);
return 0;
}
I need to read the text and find if there is more than one space between the words.
If there is change it to one.
For example if I have a text:
My name is Lukas
Program should change it to:
My name is Lukas
Any ideas?
while (*str) {
if (*str != ' ' || str[1] != ' ') *newstr++ = *str;
str++;
}
*newstr = 0;
j = 0;
for(i=0; myStr[i] != '\0'; i++) {
if(myStr[i] == ' ' && myStr[i+1] == ' ')
continue;
newStr[j] = myStr[i];
j++;
}
And don't forget to add '\0' (Which indicates the end of the string) to the end of newStr
isspace from <ctype.h> could be useful here. Here is a possible implementation:
void delete_multiple_spaces(char *dst, const char *src)
{
int previous = 0;
int c;
while ((c = *src++) != '\0')
{
if (isspace(c) && !previous)
{
previous = 1;
}
else
{
if (previous)
{
*dst++ = ' ';
previous = 0;
}
*dst++ = c;
}
}
*dst = '\0';
}
From your earlier query, I modified the logic to fit your requirement. Hope this helps.
FILE *in;
char ch,str[100],cw;
int j,i = 0;
int isSpace = 0;
in=fopen("duom.txt","r");
if(in){
while(!feof(in)){
ch=getc(in);
if(isSpace)
isSpace = (isSpace & (ch == ' '));
if(!isSpace) {
str[i] = ch;
i++;
}
if(ch == ' ')
isSpace = 1;
}
for(j=0;j<i;j++){
printf("%c",str[j]);
}
char *(strdupcompact) (const char *c)
{
int i; int p;
for (i = 0, p = 0; c[i]; i++, p++)
{
if (c[i] == ' ') while (c[i+1] == ' ') i++;
}
char *newstr = malloc(p + 1);
for (i = 0, p = 0; c[i]; i++, p++)
{
newstr[p] = c[i];
if (c[i] == ' ') while (c[i+1] == ' ') i++;
}
newstr[p] = 0;
return newstr;
}
Makes a malloced copy of your string.