Mimic Python's strip() function in C
我最近开始用C编写一个小玩具项目,一直在努力模仿python字符串对象一部分的strip()功能的最佳方法。
读一遍fscanf或sscanf表示该字符串被处理到遇到的第一个空格。
fgets也无济于事,因为我仍然有换行符。
我确实尝试了strchr()来搜索空格,并将返回的指针显式设置为" 0",但这似乎不起作用。
Python字符串的
对于尾随空格:将指针(或等效索引)设置为现有尾随 0。不断递减指针,直到指针碰到字符串开头或任何非白色字符为止;将 0设置在此终止向后扫描点之后的右边。
对于前导空格:将指针(或等效索引)设置为字符串的开头;不断增加指针,直到它碰到非白色字符(可能跟在 0后面);记住字符串的其余部分,以便第一个非白色的字符串到达??字符串的开头(类似地,随后的所有内容)。
对于strip()或trim()函数,没有标准的C实现。就是说,这是Linux内核中包含的一个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } |
我编写了C代码来实现此功能。我还编写了一些琐碎的测试,以确保我的函数执行明智的操作。
该函数将写入您提供的缓冲区,并且永远都不应写入缓冲区的末尾,因此它不容易出现缓冲区溢出安全性问题。
注意:仅Test()使用stdio.h,因此,如果仅需要函数,则只需包含ctype.h(用于isspace())和string.h(用于strlen())。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | // 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) ", s, buf, len); } main() { Test(NULL); Test(""); Test(""); Test(" "); Test("x"); Test(" x"); Test(" x "); Test(" x y z "); Test("x y z"); } |
如果要删除一行中的最后一个换行符,可以使用以下代码段:
1 2 3 | size_t s = strlen(buf); if (s && (buf[s-1] == ' ')) buf[--s] = 0; |
为了忠实地模仿Python的
或者,您可以使用C指针并修改初始字符串并获得类似的结果。
假设您的初始字符串为
"
1 2 3 | ____forty two___ ^ ptr |
如果将
".strip("_
");
1 2 3 | ____forty two\0___ ^ptr |
同样,这与Python不同。该字符串已在适当位置修改,没有第二个字符串,并且您无法还原更改(原始字符串丢失)。