0

I am writing a code for squeeze(s1,s2) that deletes each character in string s1 that matches any character in string s2 and I get "Segmentation fault (core dumped)" when I try to run the program. I believe the error comes from in how i call the function inside the main(). I am a beginner and I don't know how to call functions. Please help!

#include<stdio.h>
void squeezer(char s[], char c[]);

main()
{
    squeezer("abcdefgabcdefgabcdefg", "abcd");
}
void squeezer(char s[], char c[])
{
    int i,j,k,z;
    for(k=0; c[k] != '\0'; k++) {
        for(i=j=0;s[i] != '\0';i++) {
            if (s[i] != c[k]) {
                s[j++] = s[i];
            }
        s[j] = '\0';
        }
    }


    for(z=0; z < j; z++)
        printf("%c",s[z]);
}
  • 1
    You need to declare variables and initialize them with strings. `squeezer` cannot be called with string literals because it modifies strings passed to it, and string literals are unmodifiable. The compiler probably won't warn you about that, you are supposed to know it on your own (this is a shortcoming of the language). In addition, all functions must be declared with a return type, `main` is no exception (functions sans return type are an anachronism, allowed by compilers out of pity to ancient code). – n. m. could be an AI Jan 13 '14 at 18:52
  • 1
    Modifying a string literal is undefined behavior... –  Jan 13 '14 at 18:56

4 Answers4

3

You are passing string literal to your function and then trying to modify it. You can't modify a string literal. Modifying a string literal invokes undefined behavior. In such case you may get either expected or unexpected result You may get segmentation fault or program crash too.
You can change your main function as

int main(void)
{
    char s1[] = "abcdefgabcdefgabcdefg";
    char s2[] = "abcd";
    squeezer(s1, s2);
}  

Must read: comp.lang.c FAQ list · Question 1.32.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
haccks
  • 104,019
  • 25
  • 176
  • 264
0

String literals are "constant", read-only. You cannot change them, and that is what squeezer() tries to do.

alk
  • 69,737
  • 10
  • 105
  • 255
0

You're writing to string literals, which is undefined behaviour. If your compiler put them in read-only memory, then your program should segfault. Try making writable copies of your strings in main, like so:

int main(int argc, char** argv)
{
    char s[] = "abcdefgabcdefgabcdefg";
    char c[] = "abcd";
    squeezer(s, c);
    return 0;
}
Magnus Reftel
  • 967
  • 6
  • 19
0

Depending on the C compiler and operating system you are using, the string literal you pass to squeezer may be "read-only" -- i.e. immutable -- at run-time. This is the same mechanism meant to prevent modification of compiled code at run-time.

The fix is to allocte a character array large enough to hold s using malloc or declare a char s[80] in main or as a global variable and then use strcpy to copy your first string literal into s before passing it as the first argument to squeezer.

Alternatively, you could pass the allocated or declared array variable as a third argument to squeezer and copy the "squeezed" string into it. Or, if you want to make squeezer as robust as you can, allocate a result array with malloc in squeezer that is strlen(s) in size, use it to accumulate the "squeezed" letters, and then return the pointer to the allocted array from squeezer whose return type will have changed from void to char *.

Ned
  • 937
  • 6
  • 10