So I am kinda new to coding, but what I want to do is write a string, write one character I wish not to be in the string if it occurs. I've tried using removedChar = getchar() instead of fgets(removedChar, 2, stdin); but then I can't do the != in the if statement.
I would really appreciate your help.
int main() {
char str[20], removedChar[2];
int i, n, j;
printf("ENTER A STRING:");
fgets(str, 20, stdin);
printf("ENTER WHAT CHAR YOU WISH TO REMOVE: ");
fgets(removedChar, 2, stdin);
n = strlen(str);
for (i = 0, j = 0; i < n; i++) {
if (strcmp(str, removedChar) == 0) {
str[j] = str[i];
j++;
}
if (str[i] == ' ') {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("string after removing character = %s", str);
system("pause");
return 0;
}
Firstly this line:
if (strcmp(str, removedChar) == 0)
is comparing if two strings are identical. Please see strcmp.
You need to instead compare character against characters, instead of equality of string against string.
Having said this, you can now just simply loop over the string, and use != to rule out matching characters, and update the string accordingly with a counter.
Additionally, it is always safe to check the return value of fgets, and also check that you havn't exceeded the buffer length.
This is the code that uses these ideas:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRSIZE 20
int
main(int argc, const char *argv[]) {
char str[STRSIZE];
int i, j, removedchar;
size_t slen;
printf("Enter a string: ");
if (fgets(str, STRSIZE, stdin) == NULL) {
printf("Error reading string\n");
return 1;
}
slen = strlen(str);
if (slen > 0) {
if (str[slen-1] == '\n') {
str[slen-1] = '\0';
} else {
printf("Error: Exceeded Buffer length of %d.\n", STRSIZE);
return 1;
}
}
if(!*str) {
printf("Error: No string entered.\n");
return 1;
}
printf("Enter what character you wish to remove: ");
removedchar = getchar();
if (removedchar == '\n') {
removedchar = ' ';
printf("No character was entered. Spaces will be removed if found\n");
}
j = 0;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] != removedchar) {
str[j++] = str[i];
}
}
str[j] = '\0';
printf("Changed String = %s\n", str);
return 0;
}
You should use str[i] != removedChar[0] instead of using strcmp() which compares the full strings.
Also note that you should strip the newline character from the string read by fgets().
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char str[80], removedChar[80];
int i, n, j;
printf("ENTER A STRING: ");
if (!fgets(str, sizeof str, stdin))
return 1;
str[strcspn(str, "\n")] = '\0'; // strip the newline character if present
printf("ENTER WHAT CHAR YOU WISH TO REMOVE: ");
if (!fgets(removedChar, sizeof removedChar, stdin))
return 1;
for (i = 0, j = 0; str[i] != '\0'; i++) {
if (str[i] != removedChar[0]) {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("string after removing character = %s\n", str);
system("pause");
return 0;
}
Related
I've encountered a problem with my code where the function I made rotate_left that's supposed to take the first word in a given string and puts it at the end of that string and that function works but when it tried to activate it twice it doesn't do anything other than printing the same result the first function printed anyone got any ideas about it?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define MAX 80
void rotate_left(char str[])
{
int j = 0;
int i = 0;
char Temp[MAX];
char Temp2[MAX];
while (str[i] != ' ')
{
i++;
}
Temp[i] = '\0';
strncpy(Temp, str, i);
strcat(str, " ");
while (str[i] != '\0')
{
Temp2[j] = str[i];
i++;
j++;
}
Temp2[j] = '\0';
strcat(Temp2, Temp);
printf("%s\n", Temp2);
}
int main()
{
char str[MAX];
char Temp2[MAX];
printf("Enter Your String To Swtich The : ");
gets(str);
rotate_left(str);
rotate_left(str);
rotate_left(str);
return 0;
}
You have two bugs in these codes :
First you must copy the rotated string in the passed one, printing the result is not sufficient. Next you must remove the space at the beginning of the extracted word otherwise the new string start with a space.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define MAX 80
void rotate_left(char str[])
{
int j = 0;
int i = 0;
char Temp[MAX];
char Temp2[MAX];
// If the first space is not removed (see below), the next time
// the function is called, this loop stops immediately. It's why
// the second rotation didn't occur
while (str[i] != ' ')
{
i++;
}
Temp[i] = '\0';
strncpy(Temp, str, i);
strcat(str, " ");
i++; //<====== removes the space
while (str[i] != '\0')
{
Temp2[j] = str[i];
i++;
j++;
}
Temp2[j] = '\0';
strcat(Temp2, Temp);
strncpy(str, Temp2, strlen(Temp2) + 1); //<====== copies the string
printf("%s\n", str);
}
int main()
{
char str[MAX] = "Enter Your String To Switch The";
char Temp2[MAX];
for (int i=0; i<7; i++) rotate_left(str);
return 0;
}
Output :
Your String To Switch The Enter
String To Switch The Enter Your
To Switch The Enter Your String
Switch The Enter Your String To
The Enter Your String To Switch
Enter Your String To Switch The
Your String To Switch The Enter
I didn't handle special cases (if there is no space in the provided string for instance) and I removed the interactive dimension (gets) for the example.
Your code has issues:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define MAX 80
void rotate_left(char str[])
{
int j = 0;
int i = 0;
char Temp[MAX];
char Temp2[MAX];
while (str[i] != ' ')
{
i++;
}
in the code below you are having a security leak and a potential problem because you have temp variables in the stack and you are touching these without boundary checks: Example of a buffer overflow leading to a security leak
you need to write code with boundary checks especially when the variable is in the stack:
while (i < MAX /*or i < sizeof(str)*/ && str[i] != ' ' && str[i] != '\0' /*Null check also?*/ )
{
i++;
}
If you call this method with a string without space in it then god knows what will it result,
There are other issues as well like "strncpy(str, Temp2, strlen(Temp2) + 1);" this is not how this method is intended to be called as it should be "strncpy(str, Temp2, sizeof(str));": https://linux.die.net/man/3/strncpy
Let me write you sample code it will be faster for you to track some of the missing checks:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 80
/* just your code with safety checks so you can track why it fails */
int rotate_left(char str[], const size_t inputSize)
{
int j = 0;
int i = 0;
char Temp[MAX];
char Temp2[MAX];
while (i < inputSize && str[i] != ' ' && str[i] != '\0')
{
i++;
}
if (i == inputSize || str[i] == '\0')
{
// string without any space in it so no need to rotate?
return 0;
}
if (i + 1/*+1 to include null*/ >= MAX) {
// We dont have enough memory to handle this request
return -1;
}
strncpy(Temp, str, i);
Temp[i] = '\0';
++i;
while (i < inputSize && j < MAX && str[i] != '\0')
{
Temp2[j] = str[i];
i++;
j++;
}
if (i == inputSize) {
// String is not null terminated?
return -1;
}
if (j + 2 /*Include space and null character*/ >= MAX) {
// We dont have enough memory to handle this request
return -1;
}
Temp2[j] = ' ';
Temp2[j + 1] = '\0';
strncat(Temp2, Temp, sizeof(Temp2));
strncpy(str, Temp2, inputSize); //<====== copies the string
printf("%s\n", str);
return 0;
}
/* bit more optimization */
errno_t rotate_left_optimized(char str[], const size_t inputSize)
{
errno_t lastCall;
char temp[MAX];
int i = 0;
while (i < inputSize && str[i] != ' ' && str[i] != '\0')
{
i++;
}
if (i == inputSize || str[i] == '\0')
{
// string without any space in it so no need to rotate?
return 0;
}
const size_t inputLen = strnlen(str, inputSize);
if (i + 1 /* Include lazy space character */>= sizeof(temp)) {
// We dont have enough memory to handle this request
return -1;
}
// hidden assert(str[i] == ' ');
temp[0] = ' ';
memcpy(temp + 1, str, i);
memmove(str, str + i + 1, inputLen);
lastCall = strncat_s(str, inputSize, temp, i + 1);
if (!lastCall)
{
return lastCall;
}
return 0;
}
int main()
{
char str[MAX] = "Enter Your String To Switch The";
for (int i = 0; i < 7; i++) {
if (rotate_left_optimized(str, MAX)) {
perror("failed to rotate");
exit(EXIT_FAILURE);
}
printf("%s\n", str);
}
return 0;
}
I have program to remove the similar words from string but this program only removing at once word not a repeating words.
For example input:
sabunkerasmaskera kera
and should an output:
sabunmas
This my code:
#include <stdio.h>
#include <string.h>
void remove(char x[100], char y[100][100], char words[100]) {
int i = 0, j = 0, k = 0;
for (i = 0; x[i] != '\0'; i++) {
if (x[i] == ' ') {
y[k][j] = '\0';
k++;
j = 0;
} else {
y[k][j] = x[i];
j++;
}
}
y[k][j] = '\0';
j = 0;
for (i = 0; i < k + 1; i++) {
if (strcmp(y[i], kata) == 0) {
y[i][j] = '\0';
}
}
j = 0;
for (i = 0; i < k + 1; i++) {
if (y[i][j] == '\0')
continue;
else
printf("%s ", y[i]);
}
printf ("\n");
}
int main() {
char x[100], y[100][100], kata[100];
printf ("Enter word:\n");
gets(x);
printf("Enter word to remove:\n");
gets(words);
remove(x, y, words);
return 0;
}
My program output its:
sabunkerasmaskerara
and that should not be the case. Maybe I need your opinion to fixed this program and also I need help to make it better.
Your solution does not work because it uses strcmp to compare the string portions, which only works if the substring is at the end of the string, as this makes it null-terminated.
You should instead use strstr to locate the matches and use memmove to shift the string contents.
There are other issues in your code:
do not use gets()
y is unnecessary for this task.
words is not defined
Here is a modified version:
#include <stdio.h>
#include <string.h>
char *remove_all(char *str, const char *word) {
size_t len = strlen(word);
if (len != 0) {
char *p = str;
while ((p = strstr(p, word)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
int main() {
char str[100], word[100];
printf ("Enter string:\n");
if (!fgets(str, sizeof str, stdin))
return 1;
printf("Enter word to remove:\n");
if (!fgets(word, sizeof word, stdin))
return 1;
word[strcspn(word, "\n")] = '\0'; // strip the trailing newline if any
remove_all(str, word);
fputs(str, stdout);
return 0;
}
Im trying to make the program remove a character from a string that the user is putting in but i get an error inside the loop. (side question: is adding a character inside the string the "same" code with some small changes?)
PS New to programming...
Is this what you are trying to achieve?
Changes:
getchar() and fgets() to scanf()
added strlen() to get length of string
added lenght of input string to printf
added zero init of strings
Note: After each input with scanf() you have to press enter.
int main()
{
char str[100] = { 0 };
char ch[5] = { 0 };
int k, j;
printf("Write text:\n");
scanf("%s", str);
printf("Input was: %s\nLength: %d\n", str, strlen(str));
printf("Write a character that should be removed\n");
scanf("%s", ch);
for (k = 0, j = 0; k < strlen(str); k++)
{
if (str[k] != ch[0]) {
str[j] = str[k];
j++;
}
}
str[j] = '\0';
printf("String after removing a character: %s", str);
}
Problems with your code:
str[k] != ch would be a valid test if ch were indeed a character and not an array of characters of length 5. This is going to compare the character value of str[k] with the address &ch[0].
k < str would be a valid comparison if k was a char * pointer that was initialized at &str[0], not an int loop index starting at 0.
Corrected code:
int main(void)
{
char str[100];
char ch[5];
int k, j;
printf("Write text:\n");
//getchar();
fgets(str, 100, stdin);
printf("Input was: %s\n", str);
printf("Write a character that should be removed\n");
//getchar();
fgets(ch, 5, stdin);
for (k = 0, j = 0; k < strlen(str); k++)
{
if (str[k] != ch[0])
{
str[j] = str[k];
j++;
}
}
str[j] = '\0';
printf("String after removing a character = %s", str);
return 0;
}
Here you have two implementations. Both remove all occurrences of the char ch from the string str
First algorithm is much faster. The second slower but easy to understand
#include <stdio.h>
#include <string.h>
char *removechar(char *str, int ch)
{
char *cptr = str, *readptr = str;
while(*readptr)
{
if(*readptr == ch)
{
readptr++;
}
else
{
*cptr++ = *readptr++;
}
}
*cptr = 0;
return str;
}
char *removechar(char *str, int ch)
{
char *cpos = str;
while((cpos = strchr(cpos, ch)))
{
strcpy(cpos, cpos + 1);
}
return str;
}
int main()
{
char s[] = "Hello World";
printf("%s\n", removechar(s, 'd'));
printf("%s\n", removechar(s, 'l'));
return 0;
}
Is this what you want to achieve?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char str[100],c;
printf("Write text:\n");
fgets(str,100,stdin);
printf("Input was: %s\n", str);
printf("Write a character that should be removed\n");
c=getchar();
for(int k=0;k<strlen(str);k++){
if(str[k]==c){
for(int j=k;j<strlen(str);j++){
str[j]=str[j+1];
}
}
}
printf("String after removing a character = %s", str);
return 0;
}
I have been trying to remove the repeated consecutive characters from a string using c language for an assignment.
The input is like: sheeeiiisccommminng
The output must be like: sheiscoming
But I am getting the output: sheiscomng
I am not able to find out what went wrong here, please give your valuable insights.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main() {
char str[100];
int i, j, k, len;
printf("Enter any string: ");
fgets(str, 100, stdin);
len = strlen(str);
for (i = 0; i < len; i++) {
j = i + 1;
k = i + 2;
while (j < len) {
if (str[j] == str[i]) {
j++;
} else {
str[k] = str[j];
k++;
j++;
}
}
len = k;
}
printf("\nString after removing characters:");
for (i = 0; i < len; i++) {
printf("%c", str[i]);
}
}
You should update the length of the string with len = k; after the end of the for loop.
Note however that you should also set a null terminator at the new length when you shorten the string to make it a proper C string.
Here is a simpler version:
#include <stdio.h>
int main() {
char str[100];
int i, j;
printf("Enter any string: ");
if (fgets(str, sizeof str, stdin)) {
for (i = j = 0; str[i] != '\0'; i++) {
if (j == 0 || str[j - 1] != str[i]) {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("String after removing characters: %s\n", str);
}
return 0;
}
Not sure about your code but you could do something like
char str[]="sheeeeisssscommmiingg";
int i, j;
for(i=j=0; str[j]; i++)
{
str[i]=str[j];
for(j++; str[j]==str[i]; ++j);
}
str[i]=`\0`;
printf("\n%s", str);
After examining a character in the string via the outer loop, subsequent characters which are the same are skipped using the inner for loop.
The original string is overwritten.
At the end, the nul terminator is added to the end of the new string.
Also consider reading this.
Output in this case is:
sheiscoming
I made a program to count a given word in a sentence. When i try to run it through the compiler it say ''gets is deprecated''. So i replaced gets with fgets, but it will output 0 with every word and sentence. How can i fix this?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void gotoNextWord();
char str[1026],w[1026];
int slen, wlen, wcount, i, j;
int main()
{
fgets(str, 1026, stdin);
fgets(w, 1026, stdin);
slen = strlen(str);
wlen = strlen(w);
i = j = wcount = 0;
if(w[i] == 0)
{
printf("Please specify a program argument.\n");
}
else
{
while(i<slen)
{
if (str[i] == w[0])
{
for(j=0; j<wlen; j++)
{
if(str[i+j] != w[j])
{
gotoNextWord();
break;
}
}
if(j == wlen)
{
if(isspace(str[i+j])||ispunct(str[i+j])||str[i+j]=='\0')
{
wcount++;
i += j;
}
}
}
else
{
gotoNextWord();
}
i++;
}
printf("%d\n",wcount);
}
return 0;
}
void gotoNextWord()
{
while(isspace(str[i]) == 0 && ispunct(str[i] == 0 && str[i] != '\0'))
i++;
}
A difference between gets() and fgets() is that fgets() retains a final '\n' and gets() does not.
The "word" code is now looking for contains a '\n'.
Drop the potential '\n' and continue with previous code.
fgets(str, 1026, stdin);
str[strcspn(str, "\n")] = '\0';
fgets(w, 1026, stdin);
w[strcspn(w, "\n")] = '\0';
Recommend style/code change when using fgets()
// fgets(str, 1026, stdin);
if (fgets(str, sizeof str, stdin) == NULL) return -1;