-5

我尝试编写一个函数,该函数获取指向 char 数组的指针,从用户读取一个字符串并删除字符串开头的所有空格,直到出现第一个不是字符串的字符。最后返回开头没有空格的字符串副本。

例如,

对于输入abcd,函数应该返回指向字符串的指针abcd

对于输入123 123,函数应返回指向 string 的指针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

有什么建议么?

4

3 回答 3

4

strtok完全按预期工作。它将输入分成字符串123456.

strtok (tempRead, " "); /* Returns 123 */
strtok (NULL, " "); /* Returns 456 */

我认为您可以使用更简单的解决方案:

int i = 0;
char tempRead[30];
...
while (tempRead[i] == ' ' && tempRead[i])
  i++;
strcpy(str,tempRead+i);
于 2012-12-25T12:15:08.700 回答
3

它完全按预期工作。

第一次调用 strtok 将返回令牌的第一次出现;只要您将第一个参数提供为 NULL,后续调用将一次返回其余令牌;并且 strtok 将在令牌用完时返回 NULL。

编辑:
有些事情可能会导致奇怪的错误,所以我在这里引用手册页提到的内容以及使用时应始终牢记的内容strtok

使用这些功能时要小心。如果您确实使用它们,请注意:

  • 这些函数修改它们的第一个参数。

  • 这些函数不能用于常量字符串。

  • 定界字符的标识丢失。

  • strtok()函数在解析时使用静态缓冲区,因此它不是线程安全的。strtok_r()如果这对您很重要,请使用。

于 2012-12-25T12:15:16.633 回答
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()or isblank()from #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;
}

直到第一个空格,这个复制都是无操作的;此后,它将字符复制到它们的最终位置。

于 2012-12-25T12:35:22.073 回答