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
Related
I'm learning C and I've a problem with this school homework.
I have to make function which get two strings from user as parameters. The function removes all spaces from the first string and returns the "cleaned" strings as the other parameter.
The main function ask three strings, uses function to remove spaces and prints "cleaned" strings.
My code doesn't work as it should? What goes wrong?
#include <stdio.h>
void removeSpaces(char *, char *);
int main(){
int i, j;
char string[101], strings[1][101];
for(i = 0; i <= 2; i++){
fgets(string, 100, stdin);
for(j = 0; string[j] != '\0'; j++){
strings[i][j] = string[j];
}
strings[i][j] = '\0';
removeSpaces(strings[i], strings[i]);
}
for(i = 0; i <= 0; i++){
for(j = 0; j <= 101; j++){
printf("%c", strings[i][j]);
}
}
}
void removeSpaces(char *string1, char *string2){
int i, j;
for(i = 0; string1[i] != '\0'; i++){
if(string1[i] != ' '){
string2[i] = string1[j];
j++;
}
}
string2[i] = '\0';
}
You have to be more careful when writing code. There are several things wrong:
In removeSpaces(), you never initialize j. So it can be anything.
You are also mixing up i and j inside removeSpaces(). i should only be used to index string1, and j only for string2.
strings[1][101] is only one string, not 3. But the first for-loop in main() runs 3 times.
You don't have to print strings character by character, just printf("%s", strings[i]) or fputs(strings[i], stdout).
I'm not sure why you used a two-dimensional array strings here. You only need two strings. Renaming the variables can also help you avoid getting confused. Consider:
#include <stdio.h>
static void removeSpaces(const char *input, char *output) {
int i, o;
for(i = 0, o = 0; input[i] != '\0'; i++) {
if(input[i] != ' ') {
output[o] = input[i];
o++;
}
}
output[o] = '\0';
}
int main() {
char input[100], output[100];
fgets(input, sizeof input, stdin);
removeSpaces(input, output);
fputs(output, stdout);
}
This is a simple sorting code:
#include <stdio.h>
int main(void) {
int i, j;
char str[] = "Hello!! How are you?? I'm Fine. No Thank you.", temp;
for (i = 0; i < sizeof(str); i++) {
for (j = i + 1; j < sizeof(str); j++) {
if (str[i] > str[j]) {
temp = str[j];
str[j] = str[i];
str[i] = temp;
}
}
}
for(i = 0; i < sizeof(str); i++)
printf("%c", str[i]);
printf("%s", str);
}
I found out that I'm able to print the sorted string character by character through for loop but not printf("%s", str);, it wouldn't print anything, can someone tell me why and how to solve this?
You compute the size of your string as sizeof(str). That includes the trailing \0. The byte \0 is guaranteed to end up at the beginning of your sorted string, telling printf that the string is actually empty. You want to leave the terminating NUL past the end of the string, since it is not part of the buffer that you want to sort.
To sort only the characters of the string, without the terminator, change the loop to
int n = strlen(str);
for(i = 0; i < n; i++) {
for(j = i + 1; j < n; j++) {
You can use the strlen function to calculate length of string.
#include <stdio.h>
#include <string.h>
int main(void) {
int i, j;
char str[] = "Hello!! How are you?? I'm Fine. No Thank you.", temp;
int n = strlen(str);
for(i=0; i<n; i++){
for(j=i+1; j<n; j++){
if(str[i]>str[j]){
temp = str[j];
str[j]=str[i];
str[i]=temp;
}
}
}
for(i=0; i<n; i++) printf("%c",str[i]);
printf("%s", str);
}
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;
}
So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10
I am trying to use the following code to read a sentence(string) and then display the words of the sentence. It doesn't display as it should. What am I doing wrong?
#include <stdio.h>
#include <string.h>
#define N 100
int main()
{
char s[N];
char words[N][N];
int i=0;
int j=0;
printf("s=");
gets(s);
while ((i<strlen(s)) && (s[i]!='.'))
{
while (s[i]!= ' ')
{
sprintf(words[j],"%c", s[i]);
i++;
}
j++; i++;
}
for (i=0;i<j;i++) printf("%s ", words[i]);
return 0;
}
Your while-loop logic is wrong; it should be:
int k = 0;
while (s[i] != ' ')
words[j][k++] = s[i++];
words[j][k] = '\0';
Also, you never write a terminating null character ('\0') to words[], so the printf() call will fail.
Not tested but you should get the idea:
int size = strlen(s);
int start = 0;
for(i = 0; i < size; i++) {
if (s[i] == ' ') {
char* word = malloc((i-start)*size(char)+1); // alloc memory for a word
strcpy(word, s+size(char)*i, i-start); // copy only the selected word
word[i-start+1] = '\0'; // add '\0' at the end of string
printf("%s\n", word);
start = i + 1; // set new start index value
}
}
#include <stdio.h>
#include <string.h>
#define N 100
int main()
{
char s[N];
char words[N][N] = {0} ; /* this initial your array to 0 */
int i=0;
int j=0;
printf("s=");
gets(s);
while ((i<strlen(s)) && (s[i]!='.'))
{
while (s[i]!= ' ')
{
sprintf(words[j]+strlen(words[j]),"%c", s[i]); /* this will concat chars in words[j] */
i++;
}
j++; i++;
}
for (i=0;i<j;i++) printf("%s ", words[i]);
return 0;
}