我正在尝试解决toph.co平台中的问题。我已经编写了代码。它无法正常运行。在某些情况下给我正确的输出。但是,当我尝试使用'o'的情况时,它正在进入一个循环。也许问题就在那里。但我无法找到答案。
问题链接:https://toph.co/p/better-passwords
请帮助我解决代码中的问题。我正在使用c编程语言。由于我是编程新手,所以我没有弄错地方。
我已经尝试了很多方法。一次又一次地修改代码。现在我发疯了。
#include <stdio.h>
#include<string.h>
int main()
{
char s[40], i, j;
int len;
gets(s);
len= strlen(s);
for(i=0; i<=len; i++)
{
if(s[i] == 's')
{
s[i]= '$';
}
else if(s[i] == 'i')
{
s[i]= '!';
}
else if(s[i] == 'o')
{
s[i]= '(';
for(j=len; j>i; j--)
{
s[j]=s[j-1];
len= strlen(s);
}
s[i+1]=')';
}
else
{
continue;
}
len= strlen(s);
}
if (s[0]>='a' && s[0]<='z')
{
s[0]= s[0]- 32;
}
int new_len=strlen(s);
s[new_len]='.';
puts(s);
return 0;
}
我希望输出Un $()ph!$ t!cated。 ,但显示的是Un $()ph!$ t!cated .....“很多不需要的字符” .....
答案 0 :(得分:1)
您的字符串空字节在操作后会丢失,这是避免此类问题的最简单方法-将整个字符数组初始化为零字节:
char s[40] = {0}, // was char s[40], uninitialized !
您还注意到编译消息“ 警告:'gets'函数很危险,不应使用”吗?
gets()
很危险,因为它没有受到缓冲区溢出的保护-尝试以超过缓冲区s
容量的超长字符串运行程序,您将会崩溃:
*检测到堆栈崩溃* :已终止中止(核心已转储)
使用fgets()
代替gets(),就像这样:
fgets(s, 39, stdin);
if (s[strlen(s)-1] == '\n') s[strlen(s)-1] = '\0'; // deleting newline character
请注意,我们在此处读取BUFFER_SIZE - 1
个字符,即-比缓冲区可以容纳的字符数少40个字符(因为减少了1个字符),因为如果我们输入的是完整缓冲区大小的长字符串,则您的代码扩展字符串将再次粉碎堆栈。您需要认真对待缓冲区溢出。
答案 1 :(得分:0)
正如大多数评论员所说:您不要在扩展字符串的后面放置字符串结尾字符'\ 0'。 C中的字符串在末尾用这个额外的字符标记。需要找到字符串的结尾。
示例:字符串“ abc”实际上是由4个字符组成的序列,即“ a”,“ b”,“ c”和“ \ 0”。其长度为3,其s[3]
包含'\ 0'。
您的循环:
for(j=len; j>i; j--)
{
s[j]=s[j-1];
len= strlen(s);
}
在循环的第一轮中,s[len]
处的字符被s[len-1]
处的字符替换。这样会用字符串的最后一个(可见)字符覆盖原始的'\ 0'。
如果将循环更改为:
for (j = len; j > i; j--)
{
s[j + 1] = s[j];
}
“ \ 0”将在第一次运行时被复制。
注意1:将分配移到循环后面的len
。
注2:确保变量s
对于所有输入都足够大。
注3:看到我使用的空白吗?采用良好的代码风格并坚持下去。
答案 2 :(得分:0)
您的代码中有几个地方要覆盖“ \ 0”。 这些是:
s[j]=s[j-1];
和
s[new_len]='.';
因此纠正后的代码将是...。
int main()
{
char s[40], i, j;
int len;
gets(s);
len= strlen(s);
for(i=0; i<=len; i++)
{
if(s[i] == 's')
{
s[i]= '$';
}
else if(s[i] == 'i')
{
s[i]= '!';
}
else if(s[i] == 'o')
{
s[i]= '(';
for(j=len+1; j>i; j--) //j needs to be one more than the length
{
s[j]=s[j-1];
len= strlen(s);
}
s[i+1]=')';
}
else
{
continue;
}
len= strlen(s);
}
if (s[0]>='a' && s[0]<='z')
{
s[0]= s[0]- 32;
}
int new_len=strlen(s);
s[new_len]='.';//add a '.'
s[new_len+1] = '\0'; //add the terminating character
puts(s);
return 0;
}