【问题标题】:strtok() reading the spaces at the end of string and not returning NULLstrtok() 读取字符串末尾的空格并且不返回 NULL
【发布时间】:2015-01-14 06:42:30
【问题描述】:

我正在使用fgets() 读取包含以下由空格分隔的整数值的行:

while(fgets(str, sizeof(str), stdin) != NULL)

读取str中的字符串后,我使用strtok()将字符串转换为标记,然后使用atoi()函数将这些值转换为整数。

token = strtok(str, s);
while( token != NULL)    //If token is NULL then don't convert it to integer
int d = atoi(token);

第一个输入的输出符合预期。

输入 1:

5 1 0 3 4\n

输出 1:

d=5
d=1
d=0
d=3
d=4

现在,当我在字符串后面留一个空格并按回车时,就会出现问题。

输入 2:

5 1 0 3 4 \n

输出 2:

d=5
d=1
d=0
d=3
d=4
d=0

所以现在我的问题是:

1.如果末尾只有空格,strtok()会不会返回NULL?

2.如何区分输出中的两个零?

3.如何避免strtok() 读取最后的空格或末尾的任意数量的空格?

【问题讨论】:

  • 你错过了告诉我们strtok的实际参数。试试这个:strtok(str, " \n");
  • fgets 将在末尾保留换行符。考虑在您的分隔符字符串中包含换行符(可能还有制表符):strtok(str, " \n\t").
  • s 是什么? s 应该是分隔符
  • @harper 谢谢。它就像我使用 token = strtok(NULL, " \n"); 一样工作,即空格和换行符一起使用。

标签: c delimiter strtok


【解决方案1】:

您使用的函数不正确。作为第二个参数传递的分隔符应该是正确的。

token = strtok(str," \n\t");  //should use delimiter
while( token != NULL) 
{
   int d = atoi(token);
   printf("%d\n",d);
   token = strtok(NULL," \n\t");
}

【讨论】:

  • 谢谢@Shan。我只是在分隔符部分感到困惑,所以没有粘贴整个代码。但现在我使用了token = strtok(NULL, " \n");,它成功了。
【解决方案2】:

您的问题在于分隔符。 所有您的问题的一个解决方案是:

请在分隔符字符串中添加空格 [ ] 和换行符 [\n],还可以选择在 \t 中添加。

根据strtok()man page

char *strtok(c​​har *str, const char *delim);

delim 参数指定一组字节,用于分隔已解析字符串中的标记。

解析字符串中两个或多个连续分隔符字节的序列被认为是单个分隔符。

所以,你可以使用

char *s = " \n\t"

然后

token = strtok(str, s);

【讨论】:

  • strtok() 函数将字符串解析为标记序列。在第一次调用strtok() 时,应在 str 中指定要解析的字符串。在应解析相同字符串的每个后续调用中,str 应为 NULL。为什么在后续调用中应该为 NULL?
  • @DeepakUniyal 只有当您想再次解析 same 字符串时,它才应该为 NULL。例如,假设您想根据分隔符空格 ` ` 解析“我的名字是 Sourav”。所以在这里,你需要在第一次调用strtok时传递包含行和分隔符的字符串,它会返回“My”,现在如果你想得到“name”,你需要再次解析相同的字符串,在这种情况下,您必须将 NULL 作为第一个参数传递给 keep on 解析相同的字符串。希望这现在很清楚。 :-)
【解决方案3】:

strtok 的签名是 char *strtok(c​​har *str, const char *delim);

分隔符可以是空格 [ ]、换行符 \n 、逗号 [,] 、制表符 [\t] 以恒定有效方式分隔字符串中的两个值的任何内容都被视为分隔符。 strtok 会忽略字符串开头或结尾的分隔符。

您可以使用 n 个分隔符。根据您的字符串,您可以使用两个分隔符 1. 空格 [ ] 2. \n

改变:

1.token = strtok(str, "\n"); 2.token = strtok(NULL,"\n");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多