【发布时间】:2017-10-08 06:21:58
【问题描述】:
我试图从互联网上收集资源以了解它的工作原理和功能。基本上,每次读取字符串时,我都需要检查空格、换行符和制表符。所以我做了一个处理这种情况的函数:
#include <stdlib.h>
#include <stdio.h>
static int isspace(char c)
{
return (c == '\t' || c == '\n' || c == ' ');
}
然后,我使用下面的函数在另一个函数中实现它
char *my_strtrim(char const *string)
{
char *i;
char *s;
int ready;
i = s;
s = (char *)string;
ready = 0;
while(*i)
{
++i;
if(isspace(*i))
{
if(!ready)
{
continue ;
}
ready = 0;
}
ready = 1;
*(s++) = *i;
}
*s = 0;
return ((char *)string);
}
对于我的主要内容,我只是做了一个随机测试用例,它负责处理空格、制表符和换行符:
int main()
{
char str[] = " hello world\n !";
printf("%s",my_strtrim(str));
}
由于s 没有NULL 的结果,所以在带有i = s 的my_strtrim 函数中存在错误的输出错误。错误说:
my_strtrim.c: error: variable 's' is uninitialized when used here [-Werror,-Wuninitialized]
i = s;
^
my_strtrim.c: note: initialize the variable 's' to silence this warning
char *s;
^
= NULL
在我修复它所说的内容后(使s = NULL)我得到一个分段错误。这个问题变得令人困惑,因为它可以作为 for 循环正常工作,但不能作为 while 循环。我需要将这个问题作为一个while循环来解决。
解决方案 我的朋友给了我一个小技巧/经验法则,它使代码保持简单易懂。我有一个集群功能可以同时做很多事情;因此,我感到困惑。他指导我,告诉我让我把我的整个功能浓缩成小块。
步骤 0:初始化变量并声明
不言自明
第 1 步:获取指针字符串的位置
int step1_getPosition(char const *string)
{
int i;
i = 0;
while(my_iswhitespace(string[i]))
{
i++;
continue;
}
return (i);
}
第 2 步:复制您的字符串
char *step2_copyString(char const *string, int pos)
{
char *tmp;
int i;
i = 0;
tmp = my_strnew(my_strlen(string));
if(tmp == NULL)
return (NULL);
while (string[pos] != '\0')
tmp[i++] = string[pos++];
return (tmp);
}
第 3 步:删除空格
char *step3_removeWhite(char *str)
{
int i;
i = my_strlen(str);
while (str[i] == '\0' || my_iswhitespace(str[i]))
{
str[i] = '\0';
i--;
}
return (str);
}
第 4 步:删除额外的 NULL-BYTES ('\0')
char *step4_removeExtraNulls(char *str)
{
char *newstring;
newstring = my_strdup(str);
if(newstring == NULL)
return (NULL);
free(str);
return (newstring);
}
第 5 步:调用主函数并创建其他函数
char *my_strtrim(char const *string)
{
char *trim;
int i;
i = step1_getPosition(string);
trim = step2_copyString(string, i);
if (trim == NULL)
return (NULL);
step3_removeWhite(trim);
trim = step4_removeExtraNulls(trim);
if (trim == NULL)
return (NULL);
return (trim);
}
我得到的输出是:
hello world
!
这是正确的
【问题讨论】:
-
为什么不使用标准
isspace函数? -
顺便说一句,当您修改一个字符串
const时,您有 undefined behavior。如果要修改string的内容,不要标记为const。 -
至于你的错误,想想你做事的顺序。当你做
i = s时,s指向哪里? -
最后,我建议您多考虑一下自己在做什么。当您的函数返回 unmodified 变量
string时,您认为会发生什么?string指向哪里? -
@Someprogrammerdude,不妨继续写下它作为答案,并将另一个未回答的问题移出书本......
标签: c string error-handling while-loop trim