我最近在C中开始了一个小玩具项目,并且一直在试图模仿作为python字符串对象一部分的strip()功能的最佳方法。
读取fscanf或sscanf说明字符串被处理到遇到的第一个空格。
fgets也无济于事,因为我仍然有新的线条。 我确实尝试了strchr()来搜索空格并将返回的指针设置为'\ 0',但这似乎不起作用。
答案 0 :(得分:12)
Python字符串'strip
方法删除尾随空格和前导空格。当处理C“字符串”(char数组,\ 0终止)时,问题的两半非常不同。
对于尾随空格:将指针(或等效索引)设置为现有的尾部\ 0。继续递减指针,直到它碰到字符串的开头或任何非白色字符;在此终止 - 向后扫描点之后将\ 0设置为右。
对于前导空格:将指针(或等效索引)设置为字符串的开头;继续递增指针,直到它碰到非白色字符(可能是尾随的\ 0); memmove其余的字符串,以便第一个非白色字符串到达字符串的开头(对于后面的所有内容也是如此)。
答案 1 :(得分:9)
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;
}
答案 2 :(得分:0)
好像你想要修剪一样,快速搜索谷歌会导致this论坛帖子。
答案 3 :(得分:0)
如果你想删除,到位,一行的最后一行,你可以使用这个片段:
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不同。字符串被修改到位,没有第二个字符串,你无法恢复更改(原始字符串丢失)。
答案 4 :(得分:0)
我编写了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");
}
答案 5 :(得分:0)
很久以前我问过一个非常相似的问题。见here;有方法可以在原地和新副本上进行。