我尝试编写一个函数,该函数获取指向char数组的指针,从用户读取一个字符串并删除字符串开头的所有空格,直到出现第一个不是字符串的char。最后在开头的时候返回没有space / s的字符串副本。
例如,
对于输入abcd
,该函数应返回指向字符串abcd
的指针。
对于输入123 123
,该函数应该返回指向字符串123 123
的指针。
该功能如下所示,
void read_RemoveSpace(char * str)/**read the rest of string**/
{
char tempRead[30];
fgets(tempRead,30,stdin);
char *ptr = strtok(tempRead, " "); /**remove spaces between command and other data**/
strcpy(str,ptr); /**copy the new string without the spaces.**/
}
但是某些原因导致函数strtok()
没有按预期工作。
如果输入:
123 456
该函数只返回没有空格而不是字符串其余部分的第一部分,即它指向
123
有什么建议吗?
答案 0 :(得分:4)
strtok
完全按预期工作。它将输入分成字符串123
和456
。
strtok (tempRead, " "); /* Returns 123 */
strtok (NULL, " "); /* Returns 456 */
我认为您可以使用更简单的解决方案:
int i = 0;
char tempRead[30];
...
while (tempRead[i] == ' ' && tempRead[i])
i++;
strcpy(str,tempRead+i);
答案 1 :(得分:2)
它的工作方式完全符合预期。
第一次调用strtok将返回第一次出现的令牌;只要您将第一个参数提供为NULL,后续调用将一次返回一个标记的其余部分;当标记耗尽时,strtok将返回NULL。
编辑:
有些事情可能会导致奇怪的错误,所以我在这里引用手册页提到的内容以及使用strtok
时应该始终牢记的内容:
使用这些功能时要小心。如果您确实使用它们,请注意 的是:
这些函数修改了他们的第一个参数。
这些函数不能用于常量字符串。
分隔字符的标识将丢失。
strtok()
函数在解析时使用静态缓冲区,所以不是 线程安全。如果这对您很重要,请使用strtok_r()
。
答案 2 :(得分:0)
使用strtok()
并不是明显的方法。
void read_RemoveSpace(char *str)
{
char *dst = str;
char tempRead[30];
if (fgets(tempRead, sizeof(tempRead), stdin) != 0)
{
char *src = tempRead;
char c;
while ((c = *src++) != '\0')
{
if (c != ' ')
*dst++ = c;
}
}
*dst = '\0';
}
这会将tempRead
中的非空格复制到str
,包括换行符;如果您愿意,可以使用isspace()
中的isblank()
或#include <ctype.h>
。我不相信30对于本地字符串来说是一个很好的长度,但这就是你在问题中所拥有的。可以说,您应该指定接口中提供的字符串大小:void *read_RemoveSpace(char *buffer, size_t buflen)
。你也可以让函数返回指向字符串末尾的null的指针(从而间接地给出字符串的长度减去空格)。
void read_RemoveSpace(char *buffer, size_t buflen)
{
char *dst = buffer;
char tempRead[buflen];
if (fgets(tempRead, sizeof(tempRead), stdin) != 0)
{
char *src = tempRead;
char c;
while ((c = *src++) != '\0')
{
if (!isspace((unsigned char)c))
*dst++ = c;
}
}
*dst = '\0';
return dst;
}
没有太大的不同,但更安全。它使用本地VLA - 可变长度数组 - 它是C99的一部分。有可能放弃VLA并直接将副本复制到目标缓冲区中:
void read_RemoveSpace(char *buffer, size_t buflen)
{
char *dst = buffer;
if (fgets(buffer, buflen, stdin) != 0)
{
char *src = buffer;
char c;
while ((c = *src++) != '\0')
{
if (!isspace((unsigned char)c))
*dst++ = c;
}
}
*dst = '\0';
return dst;
}
直到第一个空格,这个复制是无操作的;之后,它将字符复制到最终位置。