How to split strings in C/CPP, similar to the split Function

Source: Internet
Author: User
Tags strtok



In python, if the Unix timestamp of the current time is required, I particularly like this:

import timetimestr = time.time()timestamp = int(timestr.split('.')[0])

Here, I like the split function very much. It is available in Java, C #, and python. It is very convenient and you don't have to worry about stepping on mines, but in C/CPP, it will be gone, this is a pity.

If you want to process a string type "192.168.1.254" and want to separate each field, what should we do? The c Standard Library has the implementation of the strtok () function.

#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){char ip_str[] = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;//printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);}

Here, strtok is non-thread-safe. This can also be seen in the second strtok call of the program. Therefore, Linux replaces strtok with strsep, source code/lib/string in linux2.6.22. C and linux-3.3 in the same file, c file is the beginning of such a paragraph:

/* *  linux/lib/string.c * *  Copyright (C) 1991, 1992  Linus Torvalds *//* * stupid library routines.. The optimized versions should generally be found * as inline code in <asm-xx/string.h> * * These are buggy as well.. * * * Fri Jun 25 1999, Ingo Oeser <[email protected]> * -  Added strsep() which will replace strtok() soon (because strsep() is *    reentrant and should be faster). Use only strsep() in new code, please. * * * Sat Feb 09 2002, Jason Thomas <[email protected]>, *                    Matthew Hawkins <[email protected]> * -  Kissed strtok() goodbye */


Because strsep is thread-safe and faster, use strsep to replace strtok. Next I will try strsep. Here, I feel that I can learn a lot of basic knowledge, such as the Lib folder of the kernel source code, by using man and checking the source code, when I am fine or writing a program, the rbtree structure used by the Linux kernel, as well as the string of the Lib folder. c, include string. the implementation of various basic functions such as strcpy and strcat in H is very classic and has been tested for a long time.

There are two interesting points in the code used by strtok.

Modify the 7th rows as follows:

#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){char *ip_str = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;//printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);}

Change char ip_str [] = "192.168.1.250"; To char * ip_str = "192.168.1.250"; then, the core dump is displayed. From the GDB and core files, the program crashes.

Program terminated with signal 11, Segmentation fault.#0  strtok () at ../sysdeps/i386/i686/strtok.S:245245  movb $0, (%edx) /* Terminate string.  */(gdb) where#0  strtok () at ../sysdeps/i386/i686/strtok.S:245#1  0x0804841e in main () at test.c:9

This code is correct in Vs, so you need to find the cause.

This reason was found in the linked http://www.cnblogs.com/longzhao1234/archive/2012/05/31/2528317.html

By reading the source code, because the function modifies the original string variable, the input parameter cannot be an immutable string (that is, the text constant area ).
For example, char * tokenremain = "abcdefghij" // It is a text constant during compilation and cannot be modified.
Strtok (tokenremain, "CDE ");
Strsep (& tokenremain, "CDE ");
When the compilation is successful, a segment error is reported during running.

In many cases, VS is much better than GCC. The CPP support of VS is the most comprehensive. Many of the authors of CPP, Daniel, are from the VC group of M $.

In addition, this time, only 16th lines are modified, and the printf statement is commented out. The Code is as follows:

#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){char ip_str[] = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);}

It crashes again, and I am not good at all.

An error occurred while analyzing the core file:

Program terminated with signal 11, Segmentation fault.#0  __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:9999  movl (%eax), %ecx /* get word (= 4 bytes) in question */(gdb) where#0  __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:99#1  0x00b9ddd5 in _IO_puts (str=0x0) at ioputs.c:37#2  0x0804846b in main () at test.c:16

It is gratifying that vs has collapsed in this sentence.

According to the prompt in the core file, the strlen function crashes at #0. In my opinion, it is the character array of the strtok stage to the end. It must be in printf ("% s \ n ", s); during printing, the buffer cannot be truncated because the '\ 0' symbol is not present, and the printf crashes due to overflow. So I declare a length of sizeof (ip_str) + 1 character array, copy ip_str, and set the last character to '\ 0', which indicates that the character ends and the result is still crashed.

If I change printf ("% s \ n", S); to printf ("% s \ t", S);, because printf is printed to the standard output, the standard output is a row buffer. For '\ n', it indicates that the row buffer is over and needs to be output. What if I don't let it output?

The output is as follows:

1681250(null)
Well, I don't know what it is, and the result has nothing to do with whether the '\ 0' symbol exists.


You must find out the problem in these two places.


Next let's take a look at the usage of strsep.

#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){char ip_str[] = "192.168.1.250";char *p = ip_str;char *ip_arr[4] ;char * s = strsep(&p, ".");int i=0;while(s){ip_arr[i] = s;s = strsep(&p, ".");i++;//printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);}

The usage is similar.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.