问题
I'm trying to figure out how to cut part of a string in C. For example you have this character string "The dog died because a car hit him while it was crossing the road" how would a function go making the sentence "a car hit him while crossing the road" or "a car hit him"
How do you go about this with C's library (or/and) a custom function?
ok I don't have the main code but this is going to be the structure of this experiment
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include "display_usage.c"/*If the user enters wrong arguments it will tell them how it should be */
void cut( const char *file, int option, int first, int last );
int main(int argc, char *argv[] ) {
FILE *fp;
char ch;
fp = fopen("test.txt", "r"); // Open file in Read mode
while (ch!=EOF) {
ch = fgetc(fp); // Read a Character
printf("%c", ch);
}
fclose(fp); // Close File after Reading
return 0;
}
void cut( const char *file, int reverse, int first, int last ) {
return;
}
回答1:
The following function cuts a given range out of a char buffer. The range is identified by startng index and length. A negative length may be specified to indicate the range from the starting index to the end of the string.
/*
* Remove given section from string. Negative len means remove
* everything up to the end.
*/
int str_cut(char *str, int begin, int len)
{
int l = strlen(str);
if (len < 0) len = l - begin;
if (begin + len > l) len = l - begin;
memmove(str + begin, str + begin + len, l - len + 1);
return len;
}
The char range is cut out by moving everything after the range including the terminating '\0'
to the starting index with memmove
, thereby overwriting the range. The text in the range is lost.
Note that you need to pass a char buffer whose contents can be changed. Don't pass string literals that are stored in read-only memory.
回答2:
strncpy
will only copy up to n
characters. Optionally you can move a pointer around in the string, and also stick a \0
into the array to terminate it early if you have writable memory.
回答3:
For such problem, it is better to write own function, it will take time, but it will pay off. A code of a function str_slice is shown below, is very similar to the JavaScripts's function string.slice (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) and to the Python's feature for making a slice on strings or arrays (https://docs.python.org/3.5/library/functions.html#slice).
It also based only on the C standard library, so must be cross-platform and to working with any compiler. If in doubt, to look on tests.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/**
* Extracts a selection of string and return a new string or NULL.
* It supports both negative and positive indexes.
*/
char *
str_slice(char str[], int slice_from, int slice_to)
{
// if a string is empty, returns nothing
if (str[0] == '\0')
return NULL;
char *buffer;
size_t str_len, buffer_len;
// for negative indexes "slice_from" must be less "slice_to"
if (slice_to < 0 && slice_from < slice_to) {
str_len = strlen(str);
// if "slice_to" goes beyond permissible limits
if (abs(slice_to) > str_len - 1)
return NULL;
// if "slice_from" goes beyond permissible limits
if (abs(slice_from) > str_len)
slice_from = (-1) * str_len;
buffer_len = slice_to - slice_from;
str += (str_len + slice_from);
// for positive indexes "slice_from" must be more "slice_to"
} else if (slice_from >= 0 && slice_to > slice_from) {
str_len = strlen(str);
// if "slice_from" goes beyond permissible limits
if (slice_from > str_len - 1)
return NULL;
buffer_len = slice_to - slice_from;
str += slice_from;
// otherwise, returns NULL
} else
return NULL;
buffer = calloc(buffer_len, sizeof(char));
strncpy(buffer, str, buffer_len);
return buffer;
}
Tests
#include <assert.h>
void
test_str_slice()
{
char str[] = "abcdefghijkl";
assert(NULL == str_slice(str, -3, -10));
assert(NULL == str_slice(str, -1, -2));
assert(NULL == str_slice(str, -1, 0));
assert(NULL == str_slice(str, 1, 0));
assert(NULL == str_slice(str, 5, 4));
assert(NULL == str_slice(str, 0, 0));
assert(NULL == str_slice(str, 10, 10));
assert(NULL == str_slice(str, -2, -2));
assert(NULL == str_slice(str, -20, -12));
assert(NULL == str_slice(str, -20, -13));
assert(NULL == str_slice(str, 12, 13));
assert(NULL == str_slice(str, 12, 20));
assert(NULL == str_slice("", 1, 2));
assert(NULL == str_slice("", -2, -1));
assert(strcmp(str_slice(str, -3, -1), "jk") == 0);
assert(strcmp(str_slice(str, -8, -3), "efghi") == 0);
assert(strcmp(str_slice(str, -10, -9), "c") == 0);
assert(strcmp(str_slice(str, -2, -1), "k") == 0);
assert(strcmp(str_slice(str, -15, -1), "abcdefghijk") == 0);
assert(strcmp(str_slice(str, -12, -2), "abcdefghij") == 0);
assert(strcmp(str_slice(str, -15, -8), "abcd") == 0);
assert(strcmp(str_slice(str, -15, -11), "a") == 0);
assert(strcmp(str_slice(str, 1, 3), "bc") == 0);
assert(strcmp(str_slice(str, 11, 100), "l") == 0);
assert(strcmp(str_slice(str, 2, 4), "cd") == 0);
assert(strcmp(str_slice(str, 3, 6), "def") == 0);
assert(strcmp(str_slice(str, 0, 1), "a") == 0);
assert(strcmp(str_slice(str, 4, 6), "ef") == 0);
assert(strcmp(str_slice(str, 1, 2), "b") == 0);
assert(strcmp(str_slice(str, 0, 3), "abc") == 0);
assert(strcmp(str_slice(str, 0, 11), "abcdefghijk") == 0);
assert(strcmp(str_slice(str, 2, 10), "cdefghij") == 0);
assert(strcmp(str_slice(str, 0, 50), "abcdefghijkl") == 0);
}
As you can see in the tests, the function to returns a string or NULL. It also has support both negative and positive indexes. This idea taken from the mentioned early features from the JavaScript and Python. So, do not pollute this answer large amount of a text, I to recommend to you to read the docs of the JavaScript and the Python.
回答4:
strstr
would be perfect for you, if you know the contents of the string.
Example:
char *str = "A dog died because a car hit him while he was crossing the road.";
char *pCh = strstr(str, "dog");
pCh
will have the address of the 'd'
in "dog"
.
回答5:
http://www.cplusplus.com/reference/cstring/
You can use functions like strstr (to get substring), strtok (split using some token),
来源:https://stackoverflow.com/questions/20342559/how-to-cut-part-of-a-string-in-c