简体   繁体   中英

In C, strtok causes segmentation fault

I'm new to C.

I'm trying to eliminate ".,;?!" from a string using strtok and then to create a simple string without any punctuation marks, but it gives me a 'Segmentation fault' after compilation. Why and how to fix it ?

char simple_s[100];
char delim[20];
memset(simple_s,0,100);
memset(delim,0,100);
strcpy(delim,strtok(s,",.;:!? "));
while(delim != NULL) {
  strcat(simple_s,delim);
  strcpy(delim,strtok(NULL,",.;:!? "));
}
printf("%s",simple_s);

There are several errors in the code. First you zero too many bytes with

char delim[20];
memset(delim,0,100);

To avoid this error, you should use

char simple_s[100];
char delim[20];
memset(simple_s,0,sizeof(simple_s));
memset(delim,0,sizeof(delim));

Next, you have used the return value of strtok() before checking if it is NULL

strcpy(delim,strtok(s,",.;:!? "));

and from there you go on to test delim for being NULL instead of checking for a NULL pointer from strtok()

while(delim != NULL) {
    strcat(simple_s,delim);
    strcpy(delim,strtok(NULL,",.;:!? "));       // <--- copying from NULL pointer
}

but delim is not even necessary, you need to work with the pointer returned by strtok() . Putting this back together, I would have

char simple_s[100] = "";                        // initialise string
char seps[] = ",.;:!? ";                        // added separators, so not to duplicate
char *tok;                                      // added to receive value from strtok()
tok = strtok(s, seps);
while(tok) {                                    // until `NULL` returned
    strcat(simple_s, tok);
    tok = strtok(NULL, seps);
}
printf("%s",simple_s);

Additionally, I have skipped over the string length checking. When you have it working, check that the new length of simple_s[] won't break, before you strcat() the next substring.

delim must be defined as a char *. Here is your code with a couple of bugs fixed:

#include <stdio.h>
#include <string.h>
#include <strings.h>

int main(int argc, char **argv)
{
  char s[100];
  char simple_s[100];
  char *delim;
  strcpy(s, "abc,def");
  memset(simple_s,0,sizeof(simple_s));
  delim = strtok(s,",.;:!? ");
  while(delim != NULL) {
    strcat(simple_s,delim);
    delim = strtok(NULL,",.;:!? ");
  }
  printf("%s",simple_s);
  return 0;
}

This outputs abcdef

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM