2012-12-25 39 views
-5

我试图写一个函数,获取指向char数组的指针,从用户读取一个字符串并删除字符串开头的所有空格,直到出现第一个不是字符串的字符。最后在开始时返回没有空格的字符串的副本。strtok不按预期工作

例如,

输入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

和你的**问题**!? – StoryTeller

+0

您面临的问题是什么?您如何调用函数?调用后存储在str中的是什么? – Vijay

+0

'strtok_r()'按预期工作,也许只是你的期望不正确... – 2012-12-25 13:00:25

回答

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); 
2

它的工作完全按照预期。

第一次调用strtok将返回第一次出现的令牌;随后的调用将一次返回一个令牌的其余部分,只要您将第一个参数提供为NULL;当它用完标记时,strtok将返回NULL。

编辑:
有些事情可能会导致莫名其妙的错误,所以我在这里引用一下手册页提到,哪些是你应该考虑使用strtok时应始终记住:

使用这些功能时一定要小心。如果你使用它们,注意 是:

  • 这些功能修改他们的第一个参数。

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

  • 分隔符的标识丢失。

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

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'; 
} 

这将复制非坯料在tempReadstr,包括换行;如果您愿意,您可以使用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; 
} 

到第一个空格,该复制是一个空操作;此后,它将字符复制到最终位置。