我刚开始学习C和学习C90。我正在尝试将一个字符串解析为一个命令,但我很难尝试删除白色字符。
我的目标是解析这样的字符串:
NA ME, NAME , 123 456, 124 , 14134, 134. 134 , 1 这方面:
NA ME,NAME,123 456,124,14134,134. 134,1所以争论中的白字符仍然存在,但是其他的白字符被移除了。
我考虑使用strtok,但我仍然想保留逗号,即使有多个连续的逗号。
直到现在我用:
void removeWhiteChars(char *s)
{
int i = 0;
int count = 0;
int inNum = 0;
while (s[i])
{
if (isdigit(s[i]))
{
inNum = 1;
}
if (s[i] == ',')
{
inNum = 0;
}
if (!isspace(s[i]) && !inNum)
s[count++] = s[i];
else if (inNum)
{
s[count++] = s[i];
}
++i;
}
s[count] = '\0'; /* adding NULL-terminate to the string */
}但是它只跳过数字,直到逗号之后才移除白色字符,这是完全错误的。
任何帮助我都会感激的,我已经坚持了两天了。
发布于 2022-05-09 19:50:32
当您遇到可能跳过的空格时,您需要执行查找头。下面的函数,每次它看到一个空格时,都会检查它是否以逗号结尾。同样,对于每个逗号,它检查并删除以下所有空格。
// Remove elements str[index] to str[index+len] in place
void splice (char * str, int index, int len) {
while (str[index+len]) {
str[index] = str[index+len];
index++;
}
str[index] = 0;
}
void removeWhiteChars (char * str) {
int index=0, seq_len;
while (str[index]) {
if (str[index] == ' ') {
seq_len = 0;
while (str[index+seq_len] == ' ') seq_len++;
if (str[index+seq_len] == ',') {
splice(str, index, seq_len);
}
}
if (str[index] == ',') {
seq_len = 0;
while (str[index+seq_len+1] == ' ') seq_len++;
if (seq_len) {
splice(str, index+1, seq_len);
}
}
index++;
}
}发布于 2022-05-09 21:17:25
解决任何解析问题的一个简短而可靠的方法是使用一个状态循环,它只不过是对原始字符串中所有字符的循环,其中使用一个(或多个)标志变量来跟踪需要跟踪的所有字符的状态。在这里,您需要知道是否正在读取逗号后面的post (后)。
这控制您如何处理下一个字符。您将使用一个简单的计数器变量来跟踪已读取的空格数,当遇到下一个字符时,如果您不是后缀逗号,则将该空格数追加到新字符串中。如果您是后逗号,则丢弃缓冲空间。(您可以使用遇到','本身作为不需要保存在变量中的标志)。
要删除','分隔符周围的空格,您可以编写一个rmdelimws()函数,该函数使用新字符串填充,将旧字符串复制为参数,并执行类似以下操作:
void rmdelimws (char *newstr, const char *old)
{
size_t spcount = 0; /* space count */
int postcomma = 0; /* post comma flag */
while (*old) { /* loop each char in old */
if (isspace (*old)) { /* if space? */
spcount += 1; /* increment space count */
}
else if (*old == ',') { /* if comma? */
*newstr++ = ','; /* write to new string */
spcount = 0; /* reset space count */
postcomma = 1; /* set post comma flag true */
}
else { /* normal char? */
if (!postcomma) { /* if not 1st char after comma */
while (spcount--) { /* append spcount spaces to newstr */
*newstr++ = ' ';
}
}
spcount = postcomma = 0; /* reset spcount and postcomma */
*newstr++ = *old; /* copy char from old to newstr */
}
old++; /* increment pointer */
}
*newstr = 0; /* nul-terminate newstr */
}(注意:更新为肯定nul-终止,如果newstr没有初始化所有为零,如下所示)
如果要在行中保存尾随空格(例如,示例中结束1后的空格),可以在nul-终止上面的字符串之前添加以下内容:
if (!postcomma) { /* if tailing whitespace wanted */
while (spcount--) { /* append spcount spaces to newstr */
*newstr++ = ' ';
}
}把它组合在一起是一个简短的例子:
#include <stdio.h>
#include <ctype.h>
void rmdelimws (char *newstr, const char *old)
{
size_t spcount = 0; /* space count */
int postcomma = 0; /* post comma flag */
while (*old) { /* loop each char in old */
if (isspace (*old)) { /* if space? */
spcount += 1; /* increment space count */
}
else if (*old == ',') { /* if comma? */
*newstr++ = ','; /* write to new string */
spcount = 0; /* reset space count */
postcomma = 1; /* set post comma flag true */
}
else { /* normal char? */
if (!postcomma) { /* if not 1st char after comma */
while (spcount--) { /* append spcount spaces to newstr */
*newstr++ = ' ';
}
}
spcount = postcomma = 0; /* reset spcount and postcomma */
*newstr++ = *old; /* copy char from old to newstr */
}
old++; /* increment pointer */
}
*newstr = 0; /* nul-terminate newstr */
}
int main (void) {
char str[] = "NA ME, NAME , 123 456, 124 , 14134, 134. 134 , 1 ",
newstr[sizeof str] = "";
rmdelimws (newstr, str);
printf ("\"%s\"\n\"%s\"\n", str, newstr);
}示例使用/输出
$ ./bin/rmdelimws
"NA ME, NAME , 123 456, 124 , 14134, 134. 134 , 1 "
"NA ME,NAME,123 456,124,14134,134. 134,1"发布于 2022-05-09 19:50:58
下面的工作,至少对您的输入字符串。我绝对没有说它的效率和优雅。我没有尝试修改s,而是写到一个新的字符串中。我遵循的算法是:
startPos初始化为0。s,直到找到逗号为止。memcpy从startPos到那个位置到一个新字符串。startPos。strcat追加最后的令牌void removeWhiteChars(char *s)
{
size_t i = 0;
size_t len = strlen(s);
char* newS = calloc(1, len);
size_t newSIndex = 0;
size_t startPos = 0;
while (i<len)
{
// find the comma
if (s[i] == ',')
{
// find the first nonspace char before the comma
ssize_t before = i-1;
while (isspace(s[before]))
{
before--;
}
// copy from startPos to before into our new string
size_t amountToCopy = (before-startPos)+1;
memcpy(newS+newSIndex, s+startPos, amountToCopy);
newSIndex += amountToCopy;
newS[newSIndex++] = ',';
// update startPos
startPos = i+1;
while (isspace(s[startPos]))
{
startPos++;
}
// update i
i = startPos+1;
}
else
{
i++;
}
}
// finally tack on the end
strcat(newS, s+startPos);
// You can return newS if you're allowed to change your function
// signature, or strcpy it to s
printf("%s\n", newS);
}我还用您的输入字符串测试了它,它可能会在其他情况下中断。
https://stackoverflow.com/questions/72176391
复制相似问题