C++ strstr不在C&x2B中工作+;4.7关于合力
在联机编译器上,该程序在输入时提供完美的输出,但在Codeforces测试中,它只是发布最后一行。调试时,我发现当使用C++ strstr不在C&x2B中工作+;4.7关于合力,c++,function,strstr,strncpy,C++,Function,Strstr,Strncpy,在联机编译器上,该程序在输入时提供完美的输出,但在Codeforces测试中,它只是发布最后一行。调试时,我发现当使用strstr()时,指针u指示地址0。我无法理解为什么该函数在其他联机编译器上工作,而不是在Codeforces上工作 编辑:好的,多亏了@Jeremy Friesner,我发现实际上是strncpy工作不正常,因为现在自定义测试用例编译器为“str”提供了错误的输出。仍然不知道为什么它在两个不同的编译器上的行为会有所不同,我应该做些什么更改 #include<iostre
strstr()
时,指针u
指示地址0
。我无法理解为什么该函数在其他联机编译器上工作,而不是在Codeforces上工作
编辑:好的,多亏了@Jeremy Friesner,我发现实际上是strncpy工作不正常,因为现在自定义测试用例编译器为“str”提供了错误的输出。仍然不知道为什么它在两个不同的编译器上的行为会有所不同,我应该做些什么更改
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<stdlib.h>
using namespace std;
int main()
{
char *s;
int length=20;
s = (char *) malloc(length*(sizeof(char)));
char c;
int count=0;
while((c=getchar())>='A')
{
if(c<='Z')
{
//cout<<count;
if(length>=count)
{
s = (char *) realloc(s,(length+=10)*sizeof(char));
}
s[count++]=c;
//printf("%p\n",s);
}
else
{
break;
}
}
char *u=s;
int o=1;
//printf("%p\n",s);
while(u)
{
char *str = (char *) malloc(o*sizeof(char));
str = strncpy(str,s,o);
//cout<<str<<endl;
char *t;
u = strstr(s+1,str);
//printf("u %p\n",u);
t=u;
int ct=0;
char *p;
while(t)
{
ct++;
p=t;
t = strstr(t+o,str);
}
ct=ct+1;
//cout<<"here"<<endl;
if(p==(s+count-o))
{
cout<<o<<" "<<ct<<endl;
}
//cout<<ct<<endl;
o++;
}
cout<<count<<" "<<1;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
char*s;
整数长度=20;
s=(char*)malloc(length*(sizeof(char));
字符c;
整数计数=0;
而((c=getchar())>='A')
{
如果(c您从未在放入s
的字符后加空终止符,因此s
不包含字符串。因此,它会导致未定义的行为将其传递给需要字符串的函数,例如strncpy
另一个大问题是使用strncpy
int o=1;
while(u)
{
char *str = (char *) malloc(o*sizeof(char));
str = strncpy(str,s,o);
u = strstr(s+1,str);
如果strlen>=o
,则strncpy
函数不会创建字符串。在这种情况下,strstr
函数只会读取缓冲区的结尾,导致未定义的行为。(具体发生的情况将取决于编译器和内存中的垃圾)
您需要将以null结尾的字符串放入str
。手动添加null终止符:
assert(o > 0);
strncpy(str, s, o-1);
str[o-1] = 0;
或者使用不同的功能:
snprintf(str, o, "%s", s);
您必须记住,字符串是一系列字符,后跟空终止符。无论何时使用需要字符串的函数,都需要确保空终止符存在
还要注意像strstrstr(t+o,str);
这样的行。如果o>strlen(t)
这会导致未定义的行为。您必须检查自己是否超出字符串的边界。如注释中所述,一个主要问题是您在读入字符串后终止字符串时不为null,这会导致奇怪的结果。具体而言,这会导致您调用未定义的行为,而ch总是一件坏事。由malloc()
分配的内存和由realloc()
分配的额外内存不保证归零
您可以通过添加以下内容来解决此问题:
s[count] = '\0';
就在之前:
char *u = s;
严格地说,您还应该检查malloc()
和realloc()
的返回值。此外,您不应该使用习惯用法:
x = realloc(x, newsize);
如果realloc()
失败,则表示您丢失了指向原始数据的指针,因此内存泄漏。安全的工作方式是:
void *space = realloc(x, newsize);
if (space == 0)
…report error etc…
x = space;
x_size = newsize;
可能还有其他问题;我没有仔细检查代码中可能出现的每一个问题。尝试在调用strstrstr()之前放置printf(“t+o=[%s]str=[%s]\n”,t+o,str);//这样,如果将参数传递到strstrstr()中,就很明显了不是您认为的那样。您不会在输入循环结束时以null终止输入字符串;您会调用未定义的行为。malloc()
和realloc()
返回的内存不保证为零。getchar()
返回一个int
。您应该将结果存储在int
对象中,这样您就可以区分它返回的EOF
值,以指示没有更多的字符可从任何有效字符值中读取。为什么要将str
设置为malloc
的返回,然后通过重新设置将该结果丢弃在下一行签名str
?在char*u=s;
adds[count]='\0';
之前。严格地说,您还应该检查malloc()
和realloc()
的返回值,如果realloc()
失败,您就会泄漏内存。