简体   繁体   English

如何在c中剪切字符串的一部分?

[英]How to cut part of a string in c?

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"我想弄清楚如何在 C 中剪切字符串的一部分。例如,你有这个字符串“狗死了,因为汽车在过马路时撞到了他”一个函数如何去使句子“a过马路时汽车撞了他”或“汽车撞了他”

How do you go about this with C's library (or/and) a custom function?你如何使用 C 的库(或/和)自定义函数来解决这个问题?

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

strncpy will only copy up to n characters. strncpy最多只能复制n字符。 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.或者,您可以在字符串中移动指针,如果您有可写内存,还可以将\\0粘贴到数组中以尽早终止它。

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.通过使用memmove将范围之后的所有内容(包括终止的'\\0'到起始索引,从而覆盖范围,从而切出字符范围。 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.不要传递存储在只读内存中的字符串文字。

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 ).函数str_slice 的代码如下所示,非常类似于 JavaScript 的函数string.slice ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice ) 和到 Python 的在字符串或数组上制作切片的功能( 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.它也仅基于 C 标准库,因此必须是跨平台的并且可以与任何编译器一起使用。 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.正如您在测试中看到的,该函数返回一个字符串或 NULL。 It also has support both negative and positive indexes.它还支持负指数和正指数。 This idea taken from the mentioned early features from the JavaScript and Python.这个想法取自前面提到的 JavaScript 和 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.所以,不要大量污染这个答案,我建议你阅读 JavaScript 和 Python 的文档。

strstr would be perfect for you, if you know the contents of the string.如果您知道字符串的内容, strstr对您来说将是完美的。

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" . pCh将具有"dog" 'd'的地址。

http://www.cplusplus.com/reference/cstring/ http://www.cplusplus.com/reference/cstring/

You can use functions like strstr (to get substring), strtok (split using some token),您可以使用 strstr(获取子字符串)、strtok(使用某些标记拆分)等函数,

You can use something similar to Python's [n:m] cut operator via a simple code but involves dynamic allocation and also preserve the original string that is an input.您可以通过简单的代码使用类似于 Python 的[n:m]剪切运算符的东西,但涉及动态分配并保留作为输入的原始字符串。

char* cutoff(const char* str, int from , int to)
{
    if (from >= to)
        return  NULL;

    char* cut = calloc(sizeof(char), (to - from) + 1);
    char* begin = cut;
    if (!cut)
        return  NULL;

    const char* fromit = str+from;
    const char* toit = str+to;
    (void)toit;
    memcpy(cut, fromit, to);
    return begin;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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