Function with two parameters removes all spaces from string - arrays

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);
}

Related

Create function which copy all values from one char array to another char array in C (segmentation fault)

I have a task. I must copy all values form one char array (sentence[]) to another empty char array sentence2[]), but I don't know why I get segmentation fault. They told us also that we must create own strlen function to check how long is string.
This is my code
#include <stdio.h>
#include <stdlib.h>
int new_strlen (char *tab)
{
int i;
for (i = 0; tab[i] != '\0'; ++i);
return i;
}
int copyText(char from[],char to[],int max)
{
int i, j;
if (new_strlen(from) <= max)
{
for(int i = 0; i != '\0'; i++) {
to[i] = from[i];
}
to[i+1] = '\0';
}
return 0;
}
int main (int argc, char *argv[])
{
char sentence[] = "C is \n a \n programming \t language";
char sentence2[1000];
copyText(sentence, sentence2, 1000);
printf("Show my array: %s \n", sentence2);
return 0;
}
Here are the bugs:
int copyText(char from[],char to[],int max)
{
int i, j; // minor problem: j is useless
if (new_strlen(from) <= max) // should be < instead of <=
{
for(int i = 0; i != '\0'; i++) { // here you declare a new i variable
// unrelated to the i declared at the beginning
to[i] = from[i];
}
to[i+1] = '\0'; // here you use again the i declared at the beginning
// which hasn't been initialized
// and i already is the index of the terminator
// therefore it should be to[i]
}
return 0;
}
This line contains two errors:
for(int i = 0; i != '\0'; i++)
i != '\0' is equivalent to i != 0. Now youv'e probably realized your error. Actually you need to test if from[i] is 0.
to[i+1] = '\0' : here i has already been incremented by the for loop, i already contains the index of the \0 terminator, therefore it should be to[i] = '\0'
And finally in this line you use the i variable declard at the beginning o the function whose content is indeterminate as you have never assigned anything to it and it is most likely this line that causes the segmentation fault: to[i+1] = '\0';
Finally there is another problem that will cause problems if the length of the string is max:
if (new_strlen(from) <= max) // should be < instead of <=
If the length of the string is max, then \0 will be put one beyond the end of the buffer, hence a buffer overflow.
You want this:
int copyText(char from[],char to[],int max)
{
if (new_strlen(from) < max)
{
int i;
for(i = 0; from[i] != '\0'; i++)
to[i] = from[i];
}
to[i] = '\0';
}
return 0;
}
Three issues with copyText
i != '\0' should be from[i] != '\0'
int i = 0 should be just i = 0 in for loop to not shadow the other i and also pointless to do it.
to[i+1] should be just to[i]
I modify my program like you said.
My program
#include <stdio.h>
#include <stdlib.h>
int new_strlen (char *tab)
{
int i;
for (i = 0; tab[i] != '\0'; ++i);
return i;
}
int copyText(char from[],char to[],int max)
{
if (new_strlen(from) < max)
{
int i;
for(int i = 0; from[i] != '\0'; i++)
{
to[i] = from[i];
}
to[i] = '\0';
}
return 0;
}
int main (int argc, char *argv[])
{
char sentence[] = "C is \n a \n programming \t language";
char sentence2[30];
copyText(sentence, sentence2, 30);
printf("Show my array: %s \n", sentence2);
return 0;
}
The output
Show my array: h�ܙ�
Why my output is wrong?
I sloved your problem. You just missed 'form[i]' in for loop of copytext() funtion. And used (new_strlen(from) <= max) instead (new_strlen(from) < max). And removed to[i+1] = '\0'; which was not needed.
#include <stdio.h>
#include <stdlib.h>
int new_strlen (char *tab)
{
int i;
for (i = 0; tab[i] != '\0'; ++i);
return i;
}
int copyText(char from[],char to[],int max)
{
if (new_strlen(from) <= max)
{
for(int i = 0; from[i] != '\0'; i++)
{
to[i] = from[i];
}
}
return 0;
}
int main (int argc, char *argv[])
{
char sentence[] = "C is \n a \n programming \t language";
char sentence2[1000];
copyText(sentence, sentence2, 1000);
printf("Show my array: %s \n", sentence2);
return 0;
}
I have a task. I must copy all values form one char array
(sentence[]) to another empty char array sentence2[]),
I you must copy all values then the third parameter of the function copyText
int copyText(char from[],char to[],int max);
is redundant. In general it does allow to copy all values.
I think that by "all values" you mean all characters of a string stored in the source array.
To copy a string from one character array to another character array the function that calculates the length of the string is not required. It is also redundant.
The return type int of the function copyText does not make a sense. The character array from which the stored string is copied shall have the qualifier const.
Standard C string functions follow the convention that the destination character array should be the first function parameter and functions should return pointer to the destination character array.
Within the function the declared variable j is not used
int i, j;
The reason of the segmentation fault is that you are using the non-initialized variable i to set the terminating zero character in the destination array. That is you declared an uninitialized variable i
int i, j;
then in the if statement in its inner loop
if (new_strlen(from) <= max)
{
for(int i = 0; i != '\0'; i++) {
^^^^^^^^^
to[i] = from[i];
}
to[i+1] = '\0';
}
you declared one more variable i which will not be alive outside the loop. The loop itself iterates never because the condition of the loop
i != '\0'
is not satisfied. The variable i was initialized by 0 and is compared with the same 0 that is written as an octal character literal.
So in this statement
to[i+1] = '\0';
there is used the initialized variable i declared in the beginning of the function before the if statement.
I am sure what you are required to write is an analog of ths atndard C function strcpy.
In this case the program can look the following way
#include <stdio.h>
char * copyText( char to[], const char from[] )
{
for ( char *p = to; ( *p++ = *from++ ) != 0; ) { /* empty */ }
return to;
}
int main (void)
{
enum { N = 1000 };
char sentence[] = "C is \n a \n programming \t language";
char sentence2[N];
printf("Show my array: %s \n", copyText(sentence2, sentence ) );
return 0;
}
The program output is
Show my array: C is
a
programming language

Making a program that implements functions that work with arrays

Doing an assignment where I have to implement some functions. One of those functions is to check if a string is a palindrome.
#include <stdio.h>
#include <stdlib.h>
char string[] = "cameron";
char string2[] = "mah";
char palindrome[] = "madam";
char notPalindrome[] = "music";
int removeChar(char *str1, char * str2, char c){
int length = 0;
for (int i = 0; str1[i] != '\0'; i++){
length++;
}
for (int i = 0; i <= length; i++){
if (str1[i] == c){
str2[i] = '*';
}
else {
str2[i] = str1[i];
}
}
for (int i = 0; i<= length; i++){
printf("%c", str2[i]);
}
}
int isPalindrome(char *str){
int length = 0;
for (int i = 0; str[i] != '\0'; i++){
length++;
}
int j = length - 1;
int reversible = 0;
for (int i = 0; i < j; i++){
if (str[i] != str[j]){
reversible++;
break;
}
j--;
}
if (reversible > 0){
printf("\nString is not a palindrome\n");
}
else {
printf("\nString is replaceable\n");
}
}
int main(){
removeChar(string, string2, 'm');
isPalindrome(palindrome);
return 0;
}
When I run this code it says the string is not a palindrome when it should be, but why is it that if I change isPalindrome(palindrome); to isPalindrome("madam"); it works.
Also Why is it that if I comment out //removeChar(string, string2, 'm');, isPalindrome() will work properly.
You have a buffer overflow. removeChar implicitly assumes that str2 is the same length as str1. So when you run this:
for (int i = 0; i <= length; i++){
if (str1[i] == c){
str2[i] = '*';
}
else {
str2[i] = str1[i];
}
}
with str1 being "cameron" and str2 being "mah", you go past the boundaries of str2 and into the memory where palindrome is stored. So after you run removeChar(string, string2, 'm');, the char[] that used to hold mah\0 now holds ca*e and the char[] that used to hold madam\0 now holds ron\0m\0. Obviously, "ron" is not a palindrome. Try printing the values of your strings after removeChar(string, string2, 'm'); and you should see this in action.
The only reason you're allowed to do this at all without a segmentation fault is because you're using char[] instead of char*, by the way. You might prefer to use pointers over arrays so things like this don't fail silently.

to remove repeated consecutive characters from a string using c

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

Kochan InsertString segmentation fault

I am working through Kochan's programming in C book and I am working on an exercise which requires a function to insert one character string inside another string, with the function call including where the string is to be inserted.
I have written the below code but I receive a segmentation fault whenever I enter the inputs. I think it's because the 'input' string is defined to the length of the user's input and then the insertString function tries to add additional characters to this string. I just can't see a way of defining the string as large enough to be able to take in additional characters. Do you think that this is the reason I am receiving a segmentation fault? Are there any other ways to go about this problem?
#include<stdio.h>
#include <string.h>
insertString(char input[], const char insert[], int position)
{
int i, j;
char temp[81];
j = strlen(input);
for(i = 0; i < position - 1; i++)
{
temp[i] = input[i];
}
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
for(j = i - j; input != '\0'; i++, j++)
{
temp[i] = input[j];
}
for(i = 0; temp[i] != '\0'; i++)
{
input[i] = temp[i];
}
input[i] = '\0';
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}
There might be other reasons as well, but the following fragment will crash for sure:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
The reason is that - since insert will not be increased or manipulated - this is an endless loop writing "indefinitely" long into temp. Once exceeding its length 80 (or a bit later) it will crash. I suppose you meant for(j = 0; insert[j] != '\0'; i++, j++), right?
Check all for loop conditions in insertString function. For example:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
is infinite loop. Because of it you access memory out of temp array bounds. It causes UB and segmentation fault. Looks like you need insert[j] != '\0' condition here.
I'm familiar with this book. The author, Stephen Kochan, has a website with answers to the odd-numbered end of chapter exercises.
The website is at classroomm.com but you'll need to look around some to find the information.
Here is the info from that site related to this exercise:
Programming in C, exercise 10-7 (3rd edition) and 9-7 (4th edition)
/* insert string s into string source starting at i
This function uses the stringLength function defined
in the chapter.
Note: this function assumes source is big enough
to store the inserted string (dangerous!) */
void insertString (char source[], char s[], int i)
{
int j, lenS, lenSource;
/* first, find out how big the two strings are */
lenSource = stringLength (source);
lenS = stringLength (s);
/* sanity check here -- note that i == lenSource
effectively concatenates s onto the end of source */
if (i > lenSource)
return;
/* now we have to move the characters in source
down from the insertion point to make room for s.
Note that we copy the string starting from the end
to avoid overwriting characters in source.
We also copy the terminating null (j starts at lenS)
as well since the final result must be null-terminated */
for ( j = lenSource; j >= i; --j )
source [lenS + j] = source [j];
/* we've made room, now copy s into source at the
insertion point */
for ( j = 0; j < lenS; ++j )
source [j + i] = s[j];
}
There's an error somewhere in your insertString function where it goes out of bounds. By the way your insertString function doesn't start with the word void.
If I substitute the insertString function which I wrote for the exercise then the program works.
#include<stdio.h>
#include <string.h>
void insertString (char source[], const char s[], int start)
{
int stringLength (const char s[]);
int lenSource = strlen (source);
int lenString = strlen (s);
int i;
if ( start > lenSource ) {
printf ("insertion point exceeds string length\n");
return;
}
// move the characters in the source string which are above the
// starting point (including the terminating null character) to make
// room for the new characters; to avoid overwriting characters the
// process begins at the end of the string
for ( i = lenSource; i >= start; --i )
source[i + lenString] = source[i];
// insert new characters
for ( i = 0; i < lenString; ++i )
source[start + i] = s[i];
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}

Reverse Words in String

For some reason, I can't get this to work! Can anyone tell me where I've gone wrong? This is supposed to reverse the words in a give string (i.e from "this is a test" to "test a is this")
#include <stdio.h>
#include <stdlib.h>
char *reverse(char const *input)
{
char *ret = (char *)malloc(sizeof(char) * strlen(input));
int length = 0;
int numWords = 1;
int i;
for(i=0; input[i]!=NULL; i++)
{
length++;
if(input[i]==' ')
numWords++;
}
char words[numWords];
int currentWord = numWords;
for(i=0; input[i]!=NULL; i++)
{
if (input[i]==' '){
currentWord--;
}else{
words[currentWord] = words[currentWord] + input[i];
}
}
for(i=0; i < numWords; i++)
{
ret = ret + words[i];
}
return ret;
}
int main(int argc, char **argv)
{
int nTestcase = 0;
int i = 0;
char inputstr[100];
char *reversedStr = NULL;
scanf("%d\n", &nTestcase);
for (i = 0; i < nTestcase; i++)
{
fgets(inputstr, 100, stdin);
reversedStr = reverse(inputstr);
printf("%s\n", reversedStr);
free(reversedStr);
memset(inputstr, 0, 100);
}
return 0;
}
words[currentWord] = words[currentWord] + input[i];
You can't add characters to each other like that expecting string concatenation. And I imagine you expect words to be an array of words (i.e. strings), but its type is not that, words is just an array of characters.
Like #Tom said, you're doing this again in the last for loop:
ret = ret + words[i];
Joseph, unlike other programming languages ( c# or PHP ), string handling functions of C are quite basic.
You cannot add strings directly, however there are a host of library functions you can use to accomplish the same task.
Check out,
strtok - Use it to split the string to words. strtok reference
strncat - Use to concatenate strings
strings in C are just byte arrays terminated with the null character ( byte with value 0).
Here is shorter/cleaner way
private char[] reverseWords(char[] words) {
int j = words.length - 1;
for (int i = 0; i < (words.length)/2; i++) {
if(i==j)
continue;
char temp = words[i];
words[i] = words[j];
words[j]=temp;
j--;
}
int lastIndex = 0;
for (int i=0;i<words.length;i++){
if(words[i]==' '){
words = reverseWord(words,lastIndex,i-1);
lastIndex=i+1;
}
}
words = reverseWord(words,lastIndex,words.length-1);
return words;
}
private char[] reverseWord(char[] words, int from, int to) {
int j=to;
for(int i=from;i<((to/2)+from/2);i++){
if(i==j) continue;
char temp = words[j];
words[j]=words[i];
words[i]=temp;
j--;
}
return words;
}

Resources