Removing a character from string in C with a dynamic string - c

So, I want to create a function which creates and returns a dynamic string based on a string s without characters c. Now, I want to be able to remove all of the desired characters, no matter the case. Additionally, the original string entered by the user should remain unchanged. Here's my attempt, it keeps telling me about an error at line 12 (noted in the comments).
One more thing: I'm not sure if I wrote the remove function well, I think it should work? All of the pointers confused me a little bit.
#include <stdio.h>
#include <stdlib.h>
char * remove(char *s, char c);
int strlen(char *s);
int main() {
char s[16], c, n[16];
printf("Please enter string: ");
scanf("%s", s);
printf("Which character do you want to remove? ");
scanf("%c", &c);
n = remove(s, c); // Place the new string in n so I wouldn't change s (the error)
printf("The new string is %s", n);
return 0;
}
int strlen(char *s)
{
int d;
for (d = 0; s[d]; d++);
return d;
}
char * remove(char *s, char c) {
char str[16], c1;
int i;
int d = strlen(s);
str = (char)calloc(d*sizeof(char)+1);
// copying s into str so I wouldn't change s, the function returns str
for (i = 0; i < d; i++) {
while(*s++ = str++);
}
// if a char in the user's string is different than c, place it into str
for (i = 0; i < d; i++) {
if (*(s+i) != c) {
c1 = *(s+i);
str[i] = c1;
}
}
return str; // the function returns a new string str without the char c
}

You declared n as 16-element array of char type:
char n[16];
So you cannot do:
n = remove(s, c);
because n is a const pointer.
Also your remove function returns a pointer to its local array, which gets destroyed as soon as your function returns. Better declare remove as
void remove(char *to, char *from, char var);
and pass n as the first parameter.

There ware so many mistakes in your program it was easier to rewrite and show you, with added comments. Note that scanf("%s... will accept only a single word, not a sentence (it stops at the first whitespace). And note that the newline will be left in the input buffer for scanf("%c... to read unless you add a space, as advised.
#include <stdio.h>
void c_remove(char *n, char *s, char c) { // renamed because remove() is predefined
while (*s) { // no need for strlen()
if (*s != c) // test if char is to be removed
*n++ = *s; // copy if not
s++; // advance source pointer
}
*n = '\0'; // terminate new string
}
int main(void) { // correct signature
char s[16], c, n[16];
printf("Please enter string: ");
scanf("%s", s);
printf("Which character do you want to remove? ");
scanf(" %c", &c); // the space before %c cleans off whitespace
c_remove(n, s, c); // pass target string pointer too
printf("The new string is %s", n);
return 0;
}
Program sessions:
Please enter string: onetwothree
Which character do you want to remove? e
The new string is ontwothr
Please enter string: onetwothree
Which character do you want to remove? o
The new string is netwthree

Related

Trouble cycling through a string

I'm having trouble looping through a string and replacing instances of a character with a new character. I'm attempting to do so with a function that I've called replace.
// C program to replace all occurrences of a character with another in a string
#include <stdio.h>
#include <string.h>
/* Function declaration */
void replace(char *string, char toReplace, char replaceWith);
int main()
{
char string[100];
char toReplace, replaceWith;
printf("Enter any string: ");
scanf("%s", string);
printf("Enter character to replace: ");
scanf("%c\n", &toReplace);
getchar();
printf("Enter character to replace '%c' with: ", toReplace);
scanf("%c\n", &replaceWith);
replace(string, toReplace, replaceWith);
// print new string
printf("%s\n", string);
return 0;
}
// Replaces the all occurrence of a character with another in given string.
void replace(char *string, char toReplace, char replaceWith)
{
for (int i = 0; i <= strlen(string); i++)
{
if (string[i] == toReplace)
{
string[i] = replaceWith;
}
}
}
Snippets of code causing me the most grief are:
printf("Enter character to replace '%c' with: ", toReplace);
Does not print what I expect it to.
if (string[i] == toReplace)
Treats string[i] as the entire string, and not the individual members of the string.
Changing
scanf("%c\n", &toReplace);
to
scanf(" %c", &toReplace); helped, as this now ignores leading whitespace.
Your replace function is OK except for a few details:
you should not recompute the length of the string at each iteration, especially as the compiler cannot assume the string to be constant since it gets modified inside the loop.
the test should be i < len where len is the length of the string. It seems incorrect to test the null terminator for replacement.
i should be defined with type size_t instead of int.
The problem you observe is linked to your usage of scanf():
"%c\n" will read the pending newline from stdin and then consume any subsequent white-space, which should not occur as the user typed the character they were prompted for. The next call will read this character, consume the newline and leave the second character typed pending in stdin. You should use scanf(" %c", &toReplace) instead.
note also that scanf("%s", string); will stop at the first white-space character and may cause a buffer overflow. Using fgets() seems a better approach for this.
Here is a modified version:
#include <stdio.h>
#include <string.h>
/* Function declaration */
void replace(char *string, char toReplace, char replaceWith);
int main() {
char string[100];
char toReplace, replaceWith;
printf("Enter any string: ");
if (!fgets(string, sizeof string, stdin))
return 1;
printf("Enter character to replace: ");
if (scanf(" %c", &toReplace) != 1)
return 1;
printf("Enter character to replace '%c' with: ", toReplace);
if (scanf(" %c", &replaceWith) != 1)
return 1;
replace(string, toReplace, replaceWith);
// print new string
printf("%s", string);
return 0;
}
// Replaces the all occurrence of a character with another in given string.
void replace(char *string, char toReplace, char replaceWith) {
for (size_t i = 0, len = strlen(string); i < len; i++) {
if (string[i] == toReplace) {
string[i] = replaceWith;
}
}
}

how to reverse the integers between two strings with changing lower to upper & upper to case alphabets in c

I have an input string such as :"Hello 12345 WoRlD"
and I want output it as : "hELLO 54321 wOrLd"
1)here the lower case should be converted to upper and vice versa
2)reverse the integers between two strings
after executing it will only prints first string only and the rest of output vanishes
Here is what I have attempted so far
#include<stdio.h>
#include<string.h>
char* casechange(char *);
main()
{
char s[30],*p,*q;
int i,j;
printf("Enter string data:");
scanf("%s",s);
q=casechange(s);
printf("Manipulated string data:%s\n",s);
}
char* casechange(char *s)
{
int i,j=strlen(s)-1,num;
for(i=0;s[i];i++)
{
if(s[i]>='a'&&s[i]<='z')
{
s[i]-=32;
}
else if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=32;
}
}
if(s[i]>='0'&&s[i]<='9'&&s[j]>='0'&&s[j]<='9')
//for(i=0;i<j;i++,j--)
//{
{
num=s[i];
s[i]=s[j];
s[j]=num;
}
//}
return s;
}
How can this be accomplished?
The problem with "after executing it will only prints first string only and the rest of output vanishes" is:
scanf("%s",s);
The scanf() '%s' format string tells scanf to read in a string, but only up to the first space. Hence, if you enter:
"Hello 12345 WoRlD"
The scanf("%s", s) will copy only "Hello" into 's'.
To fix this, change:
scanf("%s",s);
To this:
fgets(s, sizeof(s), stdin);
However, fgets() may leave a unwanted '\n' at the end of the string. The unwanted '\n' can be eliminated by inserting the following code after the fgets():
q=strchr(s,'\n');
if(q)
*q = '\0';
Then the output will be:
"hELLO 12345 wOrLd"
SPOILER ALERT!
See my version 'casechange()', which will also reverse the number.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char* casechange(char *);
int main(){
char s[30];
printf("Enter string data:");
scanf("%29[^\n]",s);//%s : separated by white space
casechange(s);
printf("Manipulated string data:%s\n", s);
return 0;
}
char* casechange(char *s){
int i;
for(i=0;s[i];i++){
if(islower(s[i]))
s[i] = toupper(s[i]);
else if(isupper(s[i]))
s[i] = tolower(s[i]);
else if(isdigit(s[i])){
int j, n;
char num[30];
sscanf(&s[i], "%29[0123456789]%n", num, &n);
for(j=0;j<n;++j)
s[i+j] = num[n-j-1];
i+=n-1;
}
}
return s;
}
else if(isdigit(s[i])){
int j, n;
char num;
sscanf(&s[i], "%*[0123456789]%n", &n);
for(j=0;j<n/2;++j){
num = s[i+j];
s[i+j] = s[i+n-j-1];
s[i+n-j-1] = num;
}
i+=n-1;
}

Character Pointers with Palindrome Checker in C

This is code I wrote that checks if a string is a palindrome or not. I need to revise this code so that it uses character pointers in it. Could someone give me some suggestions/tips...or show me how to do that? Thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
for(i=0;i < length ;i++){
if(toupper(string1[i]) != toupper(string1[length-i-1])){
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
In your code you use string1[i] to access the current element from the beginning of the string, and string1[length-i-1] to access the current element from the end of the string. You could create two pointers, pb and pe, and then move them toward each other.
To define pointers, use this:
char *pb = &string1[0]; // Or just string1, compiler will convert it to pointer
char *pe = &string1[length-1];
To advance the pointers toward each other, use pb++ and pe--.
To see if the pointers have not crossed each other , check that pb < pe. Currently, your program checks the string twice; there's no need to do that - you can stop as soon as pe becomes less than or equal to the pb.
To access the character pointed to by the current pointer, use
toupper(*pb) != toupper(*pe)
You can combine the check with advancing the pointers, like this:
toupper(*pb++) != toupper(*pe--)
Note: it is not safe to use %s, because when users enter more characters than fits in your string1 buffer overrun results. You should specify the length of the buffer, like this:
scanf("%19s", string1); // Leave one char for null terminator
I'm not sure I completely understand the question, but I think this answers it. You actually are using character pointers. char string1[20] is the same as char *string1. The difference is that you've basically assigned the pointer to a block of memory. You could access the string in this way.
char string[20] = "foo";
printf("%c\n", string[0]); // will print 'f'
printf("%c\n", *string); // will also print 'f'
printf("%c\n", string[1]); // will print the first 'o'
printf("%c\n", *(string + 1)); // will also print the first 'o'
with char * it goes like this
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
char *start=string1;
char *end=&string1[length-1];
//only check upto half
for(i=0;i <= (length-1)/2 ;i++)
{
if(toupper(*(start+i)) != toupper(*(end-i)))
{
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
cant we just copy the original string to another array, and then use strrev() to reverse the copied string and then finally compare the original string with the reversed string?
Like this
1.get new string
2.copy string to new array
3.reverse the copied string using strrev
4.use strcmp to check if both are same or not?
this seemed easier
(i am a beginner so please correct me if i am wrong)

Print a string using putch with pointers in C

So I'm trying to print an inputted string using putch and a little bit of pointers.
Here is my current code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);
c = &ch;
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}
The problem is that i can only print the first character of the string, also for some reason strlen always return 3 for strings that are 3 characters and below.
Do I have to use array for this so that I can use putch since it is limited to only 1 character output.
One of the problems is that your printer() function is not printing anything other than the first character. There are two ways of approaching this. Using pointers:
void printer(char const *c){
while ( *c != '\0' ) {
putch(*c);
c++;
}
}
And using pointer arithmetic:
void printer(char const *c) {
int x;
for ( x=0; x < strlen(c); x++ ) {
putch( *(c + x) );
}
}
The biggest problem is that you are attempting to store a string in a single character in memory. That's just asking for problems.
char ch;
scanf("%s",&ch); // NO NO NO NO NO
Instead declare your buffer (to store the string in) as an array big enough for the biggest string you expect:
char ch[512];
scanf("%s", ch);
First off, you pass a pointer to "storage for one character" to scanf. Anything that happens after that is in nsal demons territory.
Second, scanf does not allocate storage for your input, so even if you'd passed c instead of &ch, you would not be any better off.
Third, you really should be declaring your variables inside main rather than using global variables.
Something like this may be closer to what you actually want:
void output (char *c)
{
char *cp;
for (cp = c; *cp; cp++) {
putch(*cp);
}
}
int main (void)
{
char input[80];
printf("Please input a string: ");
scanf("%s\n", input);
output(input);
}
try this code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char buffer[1000];// use as a buffer
void main(){
clrscr();
printf("Enter a string: ");
scanf("%s",buffer);//read the input to the buffer
c=(char*)malloc(strlen(buffer)+1);//alloc memory with len of input + 1 byte to "\0"(end of string)
strcpy(c,buffer);//copy the input from the buffer to the new memory
printer(c);
getch();
free(c);//free the memeory
}
void printer(char *c)
{
int x;
for(x=0;x<strlen(c);x++){//move the index string pointer to next char in the string
putch(c[x]);//print the char to the screen
}
}
1)You cant use char to save a string u need char*!!!
2)You can get input to memory that not allocated!!!! because of that u must read the input to buffer after that alloc string by size of the input inside the buffer!
Your code print only first character because c is always pointing to first character of the array. For printing total string you need to increment character pointer as well
You need to do like this
void printer(char *c){
while(*c != '\0'){
putch(*c);
c++;
}
}
First calculate the length of the string & then use above implementation like this-
void printer(char *c){
int i, length;
length=strlen(c)
for(i=0;i<lenth;i++,c++){
putch(*c);
}
}
It should work I think.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;//the ch should be a array
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);//the ch don't need '&'
c = &ch;//the ch don't need '&'
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}

string rotations

#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n;i++)
{
str[n]=str[0];
for(j=0;j<n;j++)
{
str[j]=str[j+1];
}
str[n]='\0';
printf("\n %s",str);
}
return 0;
}
this program gives me all possible rotations of string
can anyone explain str[n]=str[0] and str[j]=str[j+1] meaning
instead of taking n=strlen(s) can we use n=strlen(str)
plz explain
This rotates the string. The way it does so is by moving the first character to the last place by doing str[n] = str[0] (str[n] is the string-terminating null character '\0', then shifting the whole string down one (str[j] = str[j+1]), then replacing the null at the end (str[n]='\0').
This code would, if it were using s, cause a buffer overrun if the string is longer than 14 characters. However, there's also a logic error in the code: it should be either initializing str (as a char* not int*) or scanning into s with a length bound. For instance:
scanf("%14s", s);
or
str = (char*)malloc(500);
scanf("%500s", str);
instead of taking n=strlen(s) can we use n=strlen(str)
Actually, since str is an int-pointer that is not initialized anywhere, all uses of str should be replaced by s (it's probably just a typo).
#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
char tmp_var;
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n/2;i++)
{
tmp_var = str[i];
str[i] = str[n-i];
str[n-i] = tmp_var;
}
printf("\n Rotated String is %s \n",str);
return 0;
}

Resources