我破坏了C编译器吗?

我破坏了C编译器吗?,c,string,C,String,有人能解释一下为什么在char s和char poooooop上都会出现这种情况吗? 似乎不应该同时使用两个分隔符。。这是一个bug还是我做了一些根本错误的事情? 使用GCC编译器 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char str[80] = "something:27393 somethingElse:11 info:3"; cons

有人能解释一下为什么在
char s
char poooooop
上都会出现这种情况吗? 似乎不应该同时使用两个分隔符。。这是一个bug还是我做了一些根本错误的事情? 使用GCC编译器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(){
   char str[80] = "something:27393 somethingElse:11 info:3";
   const char s[1] = " ";

   char* token;
   char* nextToken;

   /* get the first token */
   token = strtok(str, s);
   const char poooooop[1] = ":";

   printf("%s\n", poooooop);
   printf("%s\n", s);
   /* walk through other tokens */
   while( token != NULL ) {
      printf( " %s\n", token );
      token = strtok(NULL, s);
   }

   return(0);

}
#包括
#包括
#包括
int main(){
char str[80]=“某物:27393某物:11信息:3”;
常量字符s[1]=“”;
字符*令牌;
char*nextToken;
/*获取第一个令牌*/
令牌=strtok(str,s);
const char poooooop[1]=“:”;
printf(“%s\n”,poooooop);
printf(“%s\n”,s);
/*浏览其他代币*/
while(令牌!=NULL){
printf(“%s\n”,标记);
令牌=strtok(空,s);
}
返回(0);
}

strtok
的第二个参数必须是指向字符串的指针。您的
s
in

token = strtok(str, s);
表示
const char*
指针,它不是指向字符串的指针。该行为未定义。你观察到的奇怪行为只是这种未定义行为的一种表现

字符串定义为以零结尾的字符序列。您的
s
不是以零结尾的字符序列。它是一个包含单个空格字符的数组。在
s
声明中,由于
s
数组的大小不足,
文本中存在的零终止符字符“丢失”。标准C语言允许这种情况发生

如果希望该数组包含零终止符字符,则必须声明其大小为2(至少)

或者干脆

const char s[] = " ";

正如评论中所建议的那样


另外,这同样适用于你的
poooooop
数组。

你的字符串设置不正确

  const char s[1] = " ";
应该是

  const char *s = " ";

令人惊讶的是,编译器没有抱怨。

不,您没有破坏编译器(甚至没有阅读问题)在开始收集反对票之前更改您的“有趣”标题…使用char pooop[]=”;。因此,空字符被追加到数组的末尾。@EugeneSh:太晚了。这是一个完全有效的数组初始化。它不是以nul结尾的字符串。编译器可以看到大小不匹配-一边是2个字符,另一边是一个字符。你会认为会的warn@pm100:这是一个典型的、完美的、经过提炼的情况示例,值得真正的编译器警告。这正是编译器警告在世界上存在的原因。然而,即使使用
-Wall-Wextra
,GCC也无法发出警告。有什么好处?然而,它们会产生大量无用的警告,并将错误报告为警告…@昆廷:但这就是警告的作用。将正式允许但看起来可疑的事情通知用户。C语言中提供了允许终止删除的功能,以支持固定宽度的字符串。但是没有人再使用固定宽度的字符串了。C++早已不允许它了。然而,GCC警告多字符字符常量(这可能相当有用),但对此(!)保持沉默。事实上。不违法,完全允许,几乎肯定是错误->警告。
  const char s[1] = " ";
  const char *s = " ";