C语言中模仿Python的strip()函数

ffx8fchx  于 2023-01-04  发布在  Python
关注(0)|答案(5)|浏览(272)

我最近开始用C语言做一个小项目,一直在为模仿python字符串对象中的strip()功能的最佳方法而挠头。
阅读fscanf或sscanf表示字符串被处理到遇到的第一个空格。
fgets也不起作用,因为我仍然有换行符。我尝试了strchr()来搜索空格,并显式地将返回的指针设置为'\0',但似乎不起作用。

pobjuy32

pobjuy321#

Python字符串的strip方法删除了尾随和前导空格,当处理C“string”(字符数组,以\0结尾)时,问题的两部分是非常不同的。
对于尾随空格:设置一个指针(或者等价的索引)指向现有的尾部\0。持续递减指针,直到它碰到字符串的开头,或者任何非白色字符;将\0设置为正好在此向后扫描终止点之后。
对于前导空格:设置一个指向字符串开始的指针(或等价的索引);不断增加指针,直到它碰到一个非白色字符(可能是尾部的\0); memmove字符串的其余部分,使第一个非白色字符位于字符串的开头(后面的所有字符也是如此)。

vsdwdz23

vsdwdz232#

strip()或trim()函数没有标准的C实现,也就是说,Linux内核中有一个这样的实现:

char *strstrip(char *s)
{
        size_t size;
        char *end;

        size = strlen(s);

        if (!size)
                return s;

        end = s + size - 1;
        while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';

        while (*s && isspace(*s))
                s++;

        return s;
}
jv4diomz

jv4diomz3#

如果你想删除,in place,一行的最后一个换行符,你可以使用这个代码片段:

size_t s = strlen(buf);
if (s && (buf[s-1] == '\n')) buf[--s] = 0;

为了忠实地模仿Python的str.strip([chars])方法(我解释它的工作方式),你需要为一个新字符串分配空间,填充新字符串并返回它,之后,当你不再需要这个被剥离的字符串时,你需要释放它使用的内存,这样就不会有内存泄漏。
或者,您可以使用C指针并修改初始字符串,从而获得类似的结果。
假设您的初始字符串是"____forty two____\n",并且您希望去掉所有下划线和“\n”

____forty two___\n
^ ptr

如果将ptr更改为'f',并将two后面的第一个'_'替换为'\0',则结果与Python的"____forty two____\n".strip("_\n");相同

____forty two\0___\n
    ^ptr

同样,这与Python不同,字符串在原处被修改,没有第二个字符串,并且不能恢复修改(原始字符串丢失)。

b91juud3

b91juud34#

我写了C代码来实现这个函数。我还写了一些琐碎的测试来确保我的函数做了明智的事情。
此函数写入您提供的缓冲区,并且不应超过缓冲区的结尾,因此它不应出现缓冲区溢出安全问题。
注意:只有Test()使用stdio. h,所以如果你只需要这个函数,你只需要包含ctype. h(用于isspace())和string. h(用于strlen())。

// strstrip.c -- implement white space stripping for a string in C
//
// This code is released into the public domain.
//
// You may use it for any purpose whatsoever, and you don't need to advertise
// where you got it, but you aren't allowed to sue me for giving you free
// code; all the risk of using this is yours.


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


// strstrip() -- strip leading and trailing white space from a string
//
// Copies from sIn to sOut, writing at most lenOut characters.
//
// Returns number of characters in returned string, or -1 on an error.
// If you get -1 back, then nothing was written to sOut at all.

int
strstrip(char *sOut, unsigned int lenOut, char const *sIn)
{
    char const *pStart, *pEnd;
    unsigned int len;
    char *pOut;

    // if there is no room for any output, or a null pointer, return error!
    if (0 == lenOut || !sIn || !sOut)
        return -1;

    pStart = sIn;
    pEnd = sIn + strlen(sIn) - 1;

    // skip any leading whitespace
    while (*pStart && isspace(*pStart))
        ++pStart;

    // skip any trailing whitespace
    while (pEnd >= sIn && isspace(*pEnd))
        --pEnd;

    pOut = sOut;
    len = 0;

    // copy into output buffer
    while (pStart <= pEnd && len < lenOut - 1)
    {
        *pOut++ = *pStart++;
        ++len;
    }

    // ensure output buffer is properly terminated
    *pOut = '\0';
    return len;
}

void
Test(const char *s)
{
    int len;
    char buf[1024];

    len = strstrip(buf, sizeof(buf), s);

    if (!s)
        s = "**null**";  // don't ask printf to print a null string
    if (-1 == len)
        *buf = '\0';  // don't ask printf to print garbage from buf

    printf("Input: \"%s\"  Result: \"%s\" (%d chars)\n", s, buf, len);
}

main()
{
    Test(NULL);
    Test("");
    Test(" ");
    Test("    ");
    Test("x");
    Test("  x");
    Test("  x   ");
    Test("  x y z   ");
    Test("x y z");
}
q1qsirdb

q1qsirdb5#

这个潜在的“解决方案”并不像其他人提出的那样完整或彻底。这是我自己的C语言玩具项目--一个基于文本的冒险游戏,我正在和我14岁的儿子一起开发。如果你使用fgets(),那么strcspn()可能也适合你。下面的示例代码是一个基于控制台的交互式循环的开始。

#include <stdio.h>
#include <string.h> // for strcspn()

int main(void)
{
    char input[64];
    puts("Press <q> to exit..");
    do {
        
        printf("> ");
        fgets(input,64,stdin); // fgets() captures '\n'
        input[strcspn(input, "\n")] = 0; // replaces '\n' with 0 
        if (input[0] == '\0') continue; 
        printf("You entered '%s'\n", input);
        
    } while (strcmp(input,"q")!= 0); // returns 0 (false) when input = "q"

    puts("Goodbye!");
    return 0;
}

相关问题