在 C 中模仿 Python 的 strip() 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1488372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mimic Python's strip() function in C
提问by sudharsh
I started on a little toy project in C lately and have been scratching my head over the best way to mimic the strip() functionality that is part of the python string objects.
我最近开始在 C 中进行一个小玩具项目,并且一直在摸索模拟作为 python 字符串对象一部分的 strip() 功能的最佳方式。
Reading around for fscanf or sscanf says that the string is processed upto the first whitespace that is encountered.
阅读 fscanf 或 sscanf 说字符串被处理到遇到的第一个空格。
fgets doesn't help either as I still have newlines sticking around. I did try a strchr() to search for a whitespace and setting the returned pointer to '\0' explicitly but that doesn't seem to work.
fgets 也无济于事,因为我仍然有换行符。我确实尝试了 strchr() 来搜索空格并将返回的指针显式设置为 '\0' 但这似乎不起作用。
回答by Alex Martelli
Python strings' strip
method removes both trailing and leading whitespace. The two halves of the problem are very different when working on a C "string" (array of char, \0 terminated).
Python 字符串的strip
方法删除尾随和前导空格。在处理 C“字符串”(字符数组,\0 终止)时,问题的两半非常不同。
For trailing whitespace: set a pointer (or equivalently index) to the existing trailing \0. Keep decrementing the pointer until it hits against the start-of-string, or any non-white character; set the \0 to right after this terminate-backwards-scan point.
对于尾随空格:设置指向现有尾随 \0 的指针(或等效的索引)。继续递减指针,直到它碰到字符串的开头或任何非白色字符;在此终止向后扫描点之后将 \0 设置为右侧。
For leading whitespace: set a pointer (or equivalently index) to the start of string; keep incrementing the pointer until it hits a non-white character (possibly the trailing \0); memmove the rest-of-string so that the first non-white goes to the start of string (and similarly for everything following).
对于前导空格:设置一个指向字符串开头的指针(或等效的索引);不断增加指针,直到它遇到一个非白色字符(可能是尾随的 \0);记住字符串的其余部分,以便第一个非白色进入字符串的开头(对于接下来的所有内容也是如此)。
回答by Mark
There is no standard C implementation for a strip() or trim() function. That said, here's the one included in the Linux kernel:
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) = 'size_t s = strlen(buf);
if (s && (buf[s-1] == '\n')) buf[--s] = 0;
';
while (*s && isspace(*s))
s++;
return s;
}
回答by pmg
If you want to remove, in place, the final newline on a line, you can use this snippet:
如果要原地删除一行中的最后一个换行符,可以使用以下代码段:
____forty two___\n
^ ptr
To faithfully mimic Python's str.strip([chars])
method (the way I interpreted its workings), you need to allocate space for a new string, fill the new string and return it. After that, when you no longer need the stripped string you need to free the memory it used to have no memory leaks.
为了忠实地模仿 Python 的str.strip([chars])
方法(我解释其工作的方式),您需要为新字符串分配空间,填充新字符串并返回它。之后,当您不再需要剥离的字符串时,您需要释放它曾经没有内存泄漏的内存。
Or you can use C pointers and modify the initial string and achieve a similar result.
Suppose your initial string is "____forty two____\n"
and you want to strip all underscores and the '\n'
或者您可以使用 C 指针并修改初始字符串并获得类似的结果。
假设您的初始字符串是,"____forty two____\n"
并且您想去除所有下划线和 '\n'
____forty two// 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 = '##代码##';
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 = '##代码##'; // 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");
}
___\n
^ptr
If you change ptr
to the 'f' and replace the first '_' after two
with a '\0'
the result is the same as Python's "____forty two____\n".strip("_\n");
如果更改ptr
到“f”和取代第一“_”后two
有'\0'
结果是一样的Python的"____forty two____\n".strip("_\n");
Again, this is not the same as Python. The string is modified in place, there's no 2nd string and you cannot revert the changes (the original string is lost).
同样,这与 Python 不同。字符串就地修改,没有第二个字符串,您无法恢复更改(原始字符串丢失)。
回答by steveha
I wrote C code to implement this function. I also wrote a few trivial tests to make sure my function does sensible things.
我写了C代码来实现这个功能。我还编写了一些琐碎的测试,以确保我的函数执行合理的操作。
This function writes to a buffer you provide, and should never write past the end of the buffer, so it should not be prone to buffer overflow security issues.
此函数写入您提供的缓冲区,并且永远不应该写入超过缓冲区的末尾,因此它不应该容易出现缓冲区溢出安全问题。
Note: only Test() uses stdio.h, so if you just need the function, you only need to include ctype.h (for isspace()) and string.h (for strlen()).
注意:只有Test()使用stdio.h,所以如果你只需要这个函数,你只需要包含ctype.h(对于isspace())和string.h(对于strlen())。
##代码##