What C function, if any, removes all preceding spaces and tabs from a string?
In C a string is identified by a pointer, such as char *str, or possibly an array. Either way, we can declare our own pointer that will point to the start of the string:
char *c = str;
Then we can make our pointer move past any space-like characters:
while (isspace(*c))
++c;
That will move the pointer forwards until it is not pointing to a space, i.e. after any leading spaces or tabs. This leaves the original string unmodified - we've just changed the location our pointer c is pointing at.
You will need this include to get isspace:
#include <ctype.h>
Or if you are happy to define your own idea of what is a whitespace character, you can just write an expression:
while ((*c == ' ') || (*c == '\t'))
++c;
A simpler function to trim white spaces
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * trim(char * buff);
int main()
{
char buff[] = " \r\n\t abcde \r\t\n ";
char* out = trim(buff);
printf(">>>>%s<<<<\n",out);
}
char * trim(char * buff)
{
//PRECEDING CHARACTERS
int x = 0;
while(1==1)
{
if((*buff == ' ') || (*buff == '\t') || (*buff == '\r') || (*buff == '\n'))
{
x++;
++buff;
}
else
break;
}
printf("PRECEDING spaces : %d\n",x);
//TRAILING CHARACTERS
int y = strlen(buff)-1;
while(1==1)
{
if(buff[y] == ' ' || (buff[y] == '\t') || (buff[y] == '\r') || (buff[y] == '\n'))
{
y--;
}
else
break;
}
y = strlen(buff)-y;
printf("TRAILING spaces : %d\n",y);
buff[strlen(buff)-y+1]='\0';
return buff;
}
void trim(const char* src, char* buff, const unsigned int sizeBuff)
{
if(sizeBuff < 1)
return;
const char* current = src;
unsigned int i = 0;
while(current != '\0' && i < sizeBuff-1)
{
if(*current != ' ' && *current != '\t')
buff[i++] = *current;
++current;
}
buff[i] = '\0';
}
You just need to give buff enough space.
You can setup a counter to count the corresponding number of spaces, and accordingly shift the characters by that many spaces. Complexity for this ends up at O(n).
void removeSpaces(char *str) {
// To keep track of non-space character count
int count = 0;
// Traverse the given string. If current character
// is not space, then place it at index count
for (int i = 0; str[i]; i++)
if (str[i] != ' ')
str[count++] = str[i]; // increment count
str[count] = '\0';
}
Related
My code works to delete any vowels and prints the first letter of the word as a capital letter.
How can I get my expected output to work?
If the value is " I am Iron Man" (with a leading space), it works and prints "M Rn Mn".
However, without the space at the beginning of the string, my output is "m Rn Mn" but
the expected output is "M Rn Mn".
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[] = "I am Iron Man";
int i, j, len = 0;
len = strlen(str);
// Accepting input.
for (i = 0; i < len; i++) {
// Check vowels.
if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {
// delete vowel syntax
for (j = i; j < len; j++) {
// Store after removing vowels
str[j] = str[j + 1];
}
i--;
len--;
}
str[len + 1] = '\0';
}
for(i=0; str[i]!='\0'; i++)
{
//check first character is lowercase alphabet
if(i==0)
{
if((str[i]>='a' && str[i]<='z'))
str[i]=str[i]-32; //subtract 32 to make it capital
continue; //continue to the loop
}
if(str[i]==' ')//check space
{
//if space is found, check next character
++i;
//check letter if lowercase
if(str[i]>='a' && str[i]<='z')
{
str[i]=str[i]-32; //subtract 32 to make it capital
continue; //continue to the loop
}
}
}
printf("%s", str);
return 0;
}
Your problem lies with excessive use of the continue statement in the second for loop. The second continue is just plain pointless, as control reaches the end of the loop, anyway, after the point where you have that.
But the first continue is actually causing the fault: after removal of the vowels, the first character in the modified string will be a space – so, the first if block inside the second loop will be entered, and that will skip the check for a lowercase letter following the space.
Removing those continue statement will fix your code.
Also, note that you can use the islower and toupper functiosn to check for lowercase letters and convert to uppercase:
#include <stdio.h>
#include <string.h>
#include <ctype.h> // For islower and toupper
int main()
{
char str[] = "I am Iron Man";
size_t i, j, len = 0;
len = strlen(str);
// Accepting input.
for (i = 0; i < len; i++)
{
// Check vowels.
if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {
// delete vowel syntax
for (j = i; j < len; j++)
{
// Store after removing vowels
str[j] = str[j + 1];
}
i--;
len--;
}
str[len + 1] = '\0';
}
for (i = 0; str[i] != '\0'; i++)
{
//check first character is lowercase alphabet
if (i == 0)
{
if (islower(str[i])) {
str[i] = toupper(str[i]);
}
// A "continue" here is wrong ... it will skip the following check for a lowercase letter
}
if (str[i] == ' ') //check space
{
//if space is found, check next character
++i;
//check letter if lowercase
if (islower(str[i]))
{
str[i] = toupper(str[i]);
// No need for a "continue" here ... we're already at the end of the loop
}
}
}
printf("%s\n", str);
return 0;
}
I have another solution for you, that may be a bit easier to comprehend:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
char *in;
char *out;
int up = 1; // very simple state, if "up" then next character should be made upper
for (in = str, out = str; *in; in++) {
if (strchr("aeiouAEIOU", *in) != NULL) {
// do nothing
} else if (*in == ' ') {
*out++ = *in;
up = 1; // we see a space, so next letter should be upper
} else if (up) {
*out++ = toupper(*in);
up = 0; // we see a letter (or other character), ignore case
} else {
*out++ = *in;
}
}
*out = '\0';
printf("%s\n", str);
}
Or, if you don't like/understand the pointer syntax:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
int i;
int o;
int up = 1; // very simple state, if "up" then next character should be made upper
for (i = 0, o = 0; str[i]; i++) {
if (strchr("aeiouAEIOU", str[i]) != NULL) {
// do nothing
} else if (str[i] == ' ') {
str[o++] = str[i];
up = 1; // we see a space, so next letter should be upper
} else if (up) {
str[o++] = toupper(str[i]);
up = 0; // we see a letter (or other character), ignore case
} else {
str[o++] = str[i];
}
}
str[o] = '\0';
printf("%s\n", str);
}
In both cases, a very simple state is used. For more complex conditions, you should learn about state machines. In this case, the up state indicates that the next letter should be capitalised.
Note that if you want to remove leading spaces, after "removing" the vowels, you need to modify the logic a bit:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
char *in = str; // we initialize in and out here already
char *out = str;
int up = 1; // very simple state, if "up" then next chacter should be made upper
// we skip leading vowels AND spaces, this is a special case
while (*in && (strchr("aeiouAEIOU ", *in) != NULL)) {
in++;
}
// now we are at the first character that is not a vowel or space
for ( ; *in; in++) {
if (strchr("aeiouAEIOU", *in) != NULL) {
// do nothing
} else if (*in == ' ') {
*out++ = *in;
up = 1; // we see a space, so next letter should be upper
} else if (up) {
*out++ = toupper(*in);
up = 0; // we see a letter (or other character), ignore case
} else {
*out++ = *in;
}
}
*out = '\0';
printf("%s\n", str);
}
Well now you have a few examples to study that take a bit of a different approach. See if you understand the logic, and try to make it so that other characters like e.g. ( and ) also delimit words.
One of the problems is that you've got too much code. It iterates through the entire array once to strip out vowels, then again to adjust the case of the first letter of each word. Imagine this is processing data that is measured in Gb. A second pass is unnecessary.
(And, there are standard library functions like isalpha() and toupper() that you should use. Don't write code with "magic numbers".)
It's worth studying a program's 'flow control', without resorting to arbitrary 'continue' statements to affect that flow.
It's also worth starting from scratch with a minimal block of code in main(), then developing your algorithm in a function (or several). Avoid the tendency to have one long, linear program all inside main(). If you can put functionality into 'compartments', each can be developed and tested and forgotten about as the program grows more complex.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// A single pass "compacts" the data (no vowels) while also using some single operations
//tracking changing from one word to the next (first letter to uppercase.)
char *func( char *str ) {
for ( int d = 0, s = 0, up = 0; (str[d] = str[s]) != '\0'; s++)
if( !strchr( " aeiouAEIOU" + !!up, str[d] ) ) {
if( str[d] == ' ' )
up = 1;
else if( up++ < 2 )
up++, str[d] = (char)toupper( (unsigned char)str[d] );
d++; // 'd'estination idx only increments here!
}
return str;
}
int main(void) {
// sample test strings
char *strs[] = {
"I am Iron Man",
" I am Iron Man ",
"Iron Man am I",
" Iron Man am I",
"The man of steel",
" The man of steel",
};
for( size_t i = 0; i < sizeof strs/sizeof strs[0]; i++ )
puts( func( strs[i] ) );
return 0;
}
M Rn Mn
M Rn Mn
Rn Mn M
Rn Mn M
Th Mn F Stl
Th Mn F Stl
Question: Define an int function that removes all consecutive vowel repetitions from a string. The function should return the number of vowels removed and present the string without duplicates.
I am PT so Vogais is Vowels; Digite uma String is Write one String. A String sem duplicados fica assim ' %s ' e foram retiradas %d vogais is The string without duplicates is ' %s ' and where removed %d vowels.
Explanation: In portuguese we have some words with two consecutive vowels like: coordenador, coordenação (chqrlie example). But in thouse cases should be ignored in the context of this problem.
Problem: When I test a string like 'ooooo' it says the string without duplicate vogals is 'oo' and where removed 3 vowels. But it should be 'o' and 4 vowels removed. Another example with error is 'Estaa e umaa string coom duuuplicadoos', I am getting ' Esta e uma string com duplcdos ' and 8 vowels removed.
Note: This is a simple question so there isn't need to complicate. It only askes the consecutive duplicate vowels. The cases 'oOoO' -> 'oO' ,'abAb'->'abAb','abab' -> 'ab','aba'-> 'aba',... are in another chapter XD.
int Vogais(char *s) {
if (*s == 'A' || *s == 'a' || *s == 'E' || *s == 'e'
|| *s == 'I' || *s == 'i' || *s == 'O' || *s == 'o'
|| *s == 'U' || *s == 'u') return 1;
return 0;
}
int retiraVogaisRep(char *s) {
int res = 0;
for (int i = 0; i < strlen(s); i++) {
for (int j = i + 1; s[j] != '\0'; j++) {
if (s[i] == s[j] && Vogais(&s[j]) == 1) {
res++;
for (int k = j; s[k] != '\0'; k++) {
s[k] = s[k + 1];
}
}
}
}
return res;
}
int main() {
char s[38];
printf("Digite uma String:\n");
scanf("%[^\n]", s);
int res = retiraVogaisRep(s);
printf("A String sem duplicados fica assim ' %s ' e foram retiradas %d vogais.\n", s, res);
return 0;
}
Your code is too complicated: there is no need for nested loops for this task and you do not set the null terminator when shortening the string.
Here is a simpler version:
#include <stdio.h>
#include <string.h>
int retiraVogaisRep(char *s) {
int i, j; // use 2 running indices
char c, last = 0;
for (i = j = 0; (c = s[i]) != '\0'; i++) {
if (c != last || !strchr("aeiouAEIOU", c))
s[j++] = last = c;
}
s[j] = '\0'; // set the null terminator
return i - j; // return the number of bytes removed
}
int main() {
char s[100];
printf("Digite uma String:\n");
// read the user input safely with `fgets()`
if (!fgets(s, sizeof s, stdin))
return 1;
// strip the trailing newline if any
s[strcspn(s, "\n")] = '\0';
// remove duplicate consecutive vowels
int res = retiraVogaisRep(s);
printf("A String sem duplicados fica assim ' %s ' e foram retiradas %d vogais.\n", s, res);
return 0;
}
The question tag is C, but I will not post the actual code here.
The pseudocode:
function is_vowel(int c) {...}
start loop c = <src>
if next_char is past the last char then quit loop;
if is_vowel(c) and c == next_char and is_vowel(next_char)
then continue;
else
copy c to <dst>
You should elaborate on this, as the above is possibly having small issues. Nevertheless, I think this answer is somewhat shorter and gives an insight.
Update
The above is definitly have an issue, in that the next char does not copied to the output. The mistake is easy to correct, so I will leave it up to OP.
Update
Edited above code to indicate that OP wants to remove only identical duplicates. So, the case of a charcter is important.
Rather than a triple nested loop, consider a single walk down the string, looking for repeats.
#include <stdio.h>
#include <ctype.h>
int Vogais(unsigned char s) {
if (s == 'A' || s == 'a' || s == 'E' || s == 'e'
|| s == 'I' || s == 'i' || s == 'O' || s == 'o'
|| s == 'U' || s == 'u') return 1;
return 0;
}
int retiraVogaisRep(char *s) {
unsigned char *us = (unsigned char *) s;
unsigned char *dest = us;
int res = 0;
int prior = EOF;
while (*us) {
while (toupper(*us) == prior) {
us++;
res++;
}
prior = Vogais(*us) ? toupper(*us) : EOF;
*dest++ = *us++;
}
*dest = '\0';
return res;
}
int main() {
char buf[100] = "OoFreedaa";
printf("%d\t", retiraVogaisRep(buf));
printf("<%s>\n", buf);
return 0;
}
Output
3 <OFreda>
Remove consecutive duplicate vowels
You should use tolower function from ctype.h to check for vowels, that include the letter 'y', see below working code:
You can store previous character in prev and compare it to the current character, as you are case insensitive you store the tolower version.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int Vogais(char c){
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y') ;
}
int retiraVogaisRep (unsigned char *s){
if (*s == NULL)
return 0;
unsigned char t[256];
memset(t, 0, sizeof(t));
int res = 0;
int j = 0;
t[0] = s[0];
char prev = tolower(s[0]);
int len = strlen(s);
for (int i = 1; i < len; i++) {
char c = tolower(s[i]);
if (Vogais(c) && c == prev)
++res;
else
t[j++] = s[i];
prev = c;
}
memcpy(s, t, sizeof(t));
return res;
}
int main(){
char s[256];
printf("Digite uma String:\n");
scanf("%255[^\n]", s);
int res = retiraVogaisRep(s);
printf("Da String ' %s ' podem ser retiradas %d vogais.\n", s,res);
return 0;
}
Retaining the uppercase, using the Kernighan-copy
#include <stdio.h>
#include <string.h>
#include <ctype.h>
size_t remove_duplicate_vowels(char *str)
{
int old,new;
size_t dst,src;
old = 0;
for(dst=src=0; str[dst] = str[src]; old=new, src++ ) {
new = toupper( str[dst] );
if ( !strchr( "AEIOU", new )) { // Not a vowel
dst++; continue;
}
if ( new != old ) { // Not a repetition
dst++; continue;
}
}
return src - dst;
}
int main(int argc, char **argv)
{
char test[] = "Aaa bbBb CccCC d eEeee!";
char *arg;
size_t ret;
arg = argv[1] ? argv[1] : test;
ret = remove_duplicate_vowels(arg);
fprintf(stderr, "[%zu]: %s\n", ret, arg);
return 0;
}
Here is an outline of what my program is suppose to do so far.
While there are more words in inputLine:
take next word from the inputLine
if next word fits in the inputline2
add the nextword to inputline2 (doesn't work and maybe not needed)
add the inputline2 to outputBuffer (doesn't work)
format outputBuffer
Otherwise:
write the outputBuffer to the output file
empty out the outputBuffer (put \0 in position 0)
No matter what I try though, the outputline2 and/or outputBuffer never copy the contents of the inputline properly. The only reason I have inputline2 is because I was originally using fgets and putting the contents from a line in a text file into inputline. However, since my array length is suppose to be 40, it would always cut some of the words in the original line in half. If this could be avoided somehow I wouldn't even need inputline2. Either way, in both cases, the contents from word (which is just a single word from the original inputline) won't ever copy properly.
void format(FILE *ipf, FILE *outf)
{
char inputline[80];
char outputBuffer[MaxOutputLine];
char word[MaxOutputLine];
while(fgets(inputline, 80, ipf) != NULL)
{
int pos = 0;
int i;
int j = 0;
char inputline2[MaxOutputLine] = {'\0'};
while(pos != -1)
{
i=0;
pos = nextword(inputline, word, pos);
if(strlen(word) <= (40 - strlen(inputline2)))
{
while(i < strlen(word))
{
inputline2[j] = word[i];
i++;
j++;
}
j++;
printf("%s", inputline2);
}
}
}
}
int nextword(char *inputline, char *word, int pos1) //takes a word beginning from pos and puts it in word and re\
turns the new position of beginning of the next word
{
int pos2 = 0;
if(inputline[pos1] == '\0')
{
return -1;
}
if(inputline[pos1] == ' ')
{
while(inputline[pos1] == ' ')
{
pos1++;
}
}
else
{
while(inputline[pos1] != ' ' && inputline[pos1] != '\n' && inputline[pos1] != '\0')
{
word[pos2] = inputline[pos1];
pos1++;
pos2++;
}
if(pos1 == '\n' || pos1 == '\0')
{
return -1;
}
pos1++;
}
word[pos2]='\0';
return pos1;
}
As I can't format a code in comment I send it as answer.
First, I guess your nextword() is similar to:
#include <stdio.h>
#include <string.h>
int nextword(char *inputline, char *word, int pos)
{
char *ptr;
int len;
ptr = strchr(&inputline[pos], ' ');
len = ptr ? ptr - &inputline[pos] : strlen(&inputline[pos]);
strncpy(word, &inputline[pos], len);
word[len] = 0;
if (ptr == NULL)
return -1;
return pos + len + 1;
}
To make clear:
#define MaxOutputLine 40
In format() you have missed the line:
if(strlen(word) <= (40 - strlen(inputline2)))
{
while(i < strlen(word))
{
inputline2[j] = word[i];
i++;
j++;
}
inputline2[j] = ' ';/*missed, otherwise undefined, eg. \0 */
j++;
printf("%s", inputline2);
}
Some compilers have problem with long buffers on stack. You can try to add "static" before char buf[] in format().
In nextword() you have the mistake:
if(pos1 == '\n' || pos1 == '\0')
{
return -1;
}
instead of
if(inputline[pos1] == '\n' || inputline[pos1] == '\0')
{
word[pos2]='\0';
return -1;
}
In my opinion nextword() could be simplified to something like that:
int nextword(char *inputline, char *word, int pos1)
{
int pos2 = 0;
while(inputline[pos1] != ' ' && inputline[pos1] != '\n' && inputline[pos1] != '\0')
{
word[pos2] = inputline[pos1];
pos1++;
pos2++;
}
word[pos2]='\0';
if(inputline[pos1] == '\n' || inputline[pos1] == '\0')
{
return -1;
}
return pos1 + 1;
}
I want to repace multiple spaces in a string by single space, however my following code doesn't work. What's the logical mistake?
#include<stdio.h>
#include<string.h>
main()
{
char input[100];
int i,j,n,z=0;
scanf("%d",&n);
z=n;
for(i=0;i<n;i++)
scanf("%c",&input[i]);
for(i=0;i<n;i++)
{
if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))
{
--z;
for(j=i;j<n;j++)
input[j]=input[j+1];
}
}
for(i=0;i<z;i++)
printf("%c",input[i]);
printf("\n");
}
I would do something like this:
void replace_multi_space_with_single_space(char *str)
{
char *dest = str; /* Destination to copy to */
/* While we're not at the end of the string, loop... */
while (*str != '\0')
{
/* Loop while the current character is a space, AND the next
* character is a space
*/
while (*str == ' ' && *(str + 1) == ' ')
str++; /* Just skip to next character */
/* Copy from the "source" string to the "destination" string,
* while advancing to the next character in both
*/
*dest++ = *str++;
}
/* Make sure the string is properly terminated */
*dest = '\0';
}
Of course, the above function requires you to properly terminate the string, which you currently do not.
What the function above does, is basically copy the string over itself. The exception is when there is a space, when multiple spaces are simply discarded.
Since the function modifies the source string, it can not be used on string literals.
The scanf is giving you some problem: it reads the \n you give after inputting the length n. So, you will miss the last character since for loop exits. The already given answers are good enough. But if you want to follow your own logic, try this:
void main()
{
char input[100];
int i = 0,j,n = 0;
while ((input[n] = getchar()) != '\n') {
n++;
}
input[n] = '\0';
while (i < n)
{
if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))
{
for(j=i;j<n;j++)
input[j]=input[j+1];
n--;
}
else
{
i++;
}
}
printf("%s\n",input);
printf("\n");
}
if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))
case " 1 3" : when i == 0 accses input[i-1] Out-of-Bounds
scanf("%d",&n);
remain newline, (input[0] <-- '\n')
fix to
scanf("%d%*c",&n);
#include <stdio.h>
char* uniq_spc(char* str){
char *from, *to;
int spc=0;
to=from=str;
while(1){
if(spc && *from == ' ' && to[-1] == ' ')
++from;
else {
spc = (*from==' ')? 1 : 0;
*to++ = *from++;
if(!to[-1])break;
}
}
return str;
}
int main(){
char input[]= " abc de f ";
printf("\"%s\"\n", uniq_spc(input));//output:" abc de f "
return 0;
}
Why make it more complicated than it needs to be? You can use strtok to check for single whitespaces and just ignore those. Then you can use strcat to concatenate the string into a full sentence and then you're done.
This is how I did it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char *pch;
char sentence[1000];
char without[1000];
printf("Sentence: ");
fgets(sentence,1000, stdin);
strtok(sentence, "\n"); // remove any newlines
pch = strtok(sentence, " ");
while(pch != NULL) {
strcat(without, pch);
strcat(without, " \0");
pch = strtok(NULL, " ");
}
without[strlen(without)-1] = '\0'; // remove extra whitespace at the end
printf("|%s|\n",without);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void remove_blanks(char* s);
int main()
{
char const s[] = {'1',' ',' ','2',' ',' ','3'};
remove_blanks(s);
printf("%s",s);
return 0;
}
void remove_blanks(char* s){
int i=0, delta=0, cnt=0;
for (i=0;s[i];++i){
if (s[i]==' ') cnt++;
if (cnt>1){
delta+=1;
cnt=0;
}
s[i-delta]=s[i];
if(delta>0) s[i]='\0';
}
}
You cant try this simple code:
#include <stdio.h>
#define IN 1
#define OUT 0
int main() {
int c, spaces, state;
spaces = 0;
state = OUT;
while ((c = getchar()) != EOF) {
if ( c == ' ') {
++spaces;
state = OUT;
}
else if (state == OUT) {
state = IN;
spaces = 0;
}
if (c == ' ' && spaces > 1 && state == OUT)
c = 0;
putchar(c);
}
return 0;
}
You have to fix the following for loop. the limit of your for loop should be z and not n
for(j=i;j<n;j++)
input[j]=input[j+1];
by
for(j=i;j<z;j++)
input[j]=input[j+1];
BTW: the fist charachter get by your scanf() (which read charachters) is newline (\n). this newline come from the first scanf() of decimal(%d)
#include<stdio.h>
#include<string.h>
int main(void)
{
char input[1000];
int i=0;
gets(input);
for(i=0;input[i]!='\0';i++)
{
if(input[i]!=' ' || input[i+1]!=' ')
printf("%c",input[i]);
}
return 0;
}
How do you remove spaces and special characters from a string?
I couldn't find a single answer while googling. There were a lot related to other languages, but not C. Most of them mentioned the use of regex, which isn't C standard (?).
Removing a simple space is easy:
char str[50] = "Remove The Spaces!!";
Then a simple loop with a if-statement:
if (str[i] != ' ');
Output would be:
RemoveTheSpaces!!
What do I add to the if-statement so it would recognize special characters and remove them?
My definition of special characters:
Characters not included in this list:
A-Z a-z 0-9
This is probably not the most efficient way of achieving this but it will get the job done fairly fast.
Note: this code does require you to include <string.h> and <ctype.h>
char str[50] = "Remove The Spaces!!";
char strStripped[50];
int i = 0, c = 0; /*I'm assuming you're not using C99+*/
for(; i < strlen(str); i++)
{
if (isalnum(str[i]))
{
strStripped[c] = str[i];
c++;
}
}
strStripped[c] = '\0';
There are millions of different ways this can be done. Here is just one example that is not using any additional storage and performs the removal of unneeded characters "in-place":
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
static void my_strip(char *data)
{
unsigned long i = 0; /* Scanning index */
unsigned long x = 0; /* Write back index */
char c;
/*
* Store every next character in `c` and make sure it is not '\0'
* because '\0' indicates the end of string, and we don't want
* to read past the end not to trigger undefined behavior.
* Then increment "scanning" index so that next time we read the
* next character.
*/
while ((c = data[i++]) != '\0') {
/* Check if character is either alphabetic or numeric. */
if (isalnum(c)) {
/*
* OK, this is what we need. Write it back.
* Note that `x` will always be either the same as `i`
* or less. After writing, increment `x` so that next
* time we do not overwrite the previous result.
*/
data[x++] = c;
}
/* else — this is something we don't need — so we don't increment the
`x` while `i` is incremented. */
}
/* After all is done, ensure we terminate the string with '\0'. */
data[x] = '\0';
}
int main()
{
/* This is array we will be operating on. */
char data[512];
/* Ask your customer for a string. */
printf("Please enter a string: ");
if (fgets(data, sizeof(data), stdin) == NULL) {
/* Something unexpected happened. */
return EXIT_FAILURE;
}
/* Show the customer what we read (just in case :-)) */
printf("You have entered: %s", data);
/*
* Call the magic function that removes everything and leaves
* only alphabetic and numberic characters.
*/
my_strip(data);
/*
* Print the end result. Note that newline (\n) is there
* when we read the string
*/
printf("Stripped string: %s\n", data);
/* Our job is done! */
return EXIT_SUCCESS;
}
I put a lot of comments in there so hopefully the code doesn't need explanation. Hope it helps. Good Luck!
This is just a silly suggestion.
char ordinary[CHAR_MAX] = {
['A']=1,['B']=1,['C']=1,['D']=1,['E']=1,['F']=1,['G']=1,['H']=1,['I']=1,
['J']=1,['K']=1,['L']=1,['M']=1,['N']=1,['O']=1,['P']=1,['Q']=1,['R']=1,
['S']=1,['T']=1,['U']=1,['V']=1,['W']=1,['X']=1,['Y']=1,['Z']=1,
['a']=1,['b']=1,['c']=1,['d']=1,['e']=1,['f']=1,['g']=1,['h']=1,['i']=1,
['j']=1,['k']=1,['l']=1,['m']=1,['n']=1,['o']=1,['p']=1,['q']=1,['r']=1,
['s']=1,['t']=1,['u']=1,['v']=1,['w']=1,['x']=1,['y']=1,['z']=1,
['0']=1,['1']=1,['2']=1,['3']=1,['4']=1,['5']=1,['6']=1,['7']=1,['8']=1,
['9']=1,
};
int is_special (int c) {
if (c < 0) return 1;
if (c >= CHAR_MAX) return 1;
return !ordinary[c];
}
void remove_spaces_and_specials_in_place (char *str) {
if (str) {
char *p = str;
for (; *str; ++str) {
if (!is_special(*str)) *p++ = *str;
}
*p = '\0';
}
}
Using your if statement:
if (str[i] != ' ');
With a little logic (the characters have to be in the range a-z or A-Z or 0-9:
If ( !('a' <= str[i] && 'z' >= str[i]) &&
!('A' <= str[i] && 'Z' >= str[i]) &&
!('0' <= str[i] && '9' >= str[i])) then ignore character.
This is Ascii Code Range
Char:Dec
0:48, 9:57
A:65, Z:90
a:97, z:122
try this:
char str[50] = "Remove The Spaces!!";
int i =0;
for(; i<strlen(str); i++)
{
if(str[i]>=48 && str[i]<=57 || str[i]>=65 && str[i]<=90 || str[i]>=97 && str[i]<=122)
//This is equivalent to
//if(str[i]>='0' && str[i]<='9' || str[i]>='A' && str[i]<='Z' || str[i]>='a' && str[i]<='z')
printf("alphaNumeric:%c\n", str[i]);
else
{
printf("special:%c\n", str[i]);
//remove that
}
}
#include <stdio.h>
#include <string.h>
main()
{
int i=0, j=0;
char c;
char buff[255] = "Remove The Spaces!!";
for(; c=buff[i]=buff[j]; j++){
if(c>='A' && c<='Z' || c>='a' && c<='z' || c>='0' && c<='9'){
i++;
}
}
printf("char buff[255] = \"%s\"\n", buff);
}
include < stdio.h >
int main()
{
char a[100];
int i;
printf("Enter the character : ");
gets(a);
for (i = 0; a[i] != '\0'; i++) {
if ((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && a[i] <= 'Z')
|| (a[i] - 48 >= 0 && a[i] - 48 <= 9)) {
printf("%c", a[i]);
} else {
continue;
}
}
return 0;
}