[英]What is wrong in my concatenation function mystrcat(char*, char*, char*)?
I was interviewed recently and asked to write mystrcat(*s1, *s2, *s3)
where s1
and s2
are source string and the concatenated results are given by s3
. 我最近接受了采访并要求编写
mystrcat(*s1, *s2, *s3)
,其中s1
和s2
是源字符串,连接结果由s3
给出。 I was told, don't worry about memory allocation of s3
and assume s1
and s2
are not null / invalid strings. 我被告知,不要担心
s3
内存分配,并假设s1
和s2
不是空/无效字符串。 So I wrote the following lame (crude) program. 所以我写了下面的蹩脚(粗)程序。 I was told there is something wrong with
s3
or something can go wrong with s3
. 有人告诉我有什么毛病
s3
或东西可以去错了s3
。 Could you please tell what it is/ could that be? 你能告诉它它是什么/可能是什么?
void mystrcat(char *s1, char *s2, char *s3)
{
if (! (s1 || s2 || s3)) return; // one/more pointers are invalid
// copy string s1 into s3
while(*s1) {
*s3 = *s1;
s1++;
s3++;
}
// concatenate string s2 into s3
while(*s2) {
*s3 = *s2;
s2++;
s3++;
}
*s3 = '\0';
}
Could you please tell me what is wrong here? 你能告诉我这里有什么问题吗? What would be more professional way of doing it?
做什么会更专业呢?
if (! (s1 || s2 || s3) return; // one/more pointers are invalid
应该
if ((!s1) || (!s2) || (!s3)) return;
Two possible points 两个可能的点
First, you were told that the inputs and the otput pointed to valid strings, so the test for validity is arguably not needed. 首先,您被告知输入和输出指向有效字符串,因此可以说不需要测试有效性。 And if it were needed you should have failed noisily.
如果需要,你应该吵闹失败。 Better would have been:
更好的是:
void mystrcat(char *s1, char *s2, char *s3)
{
ASSERT( s1 );
ASSERT( s2 );
ASSERT( s3 );
....
Then you basically wrote strcat/strcpy when you could have reused them: 然后你基本上写了strcat / strcpy,你可以重用它们:
void mystrcat(char *s1, char *s2, char *s3)
{
strcpy( s3, s1 );
strcat( s3, s2 );
}
And if I were interviewing you for anything other than a junior post, I would have eexpected you to point out to me that the mystrcat interface as specified is very pporly designed and given details of how you would improve it. 如果我正在采访你以外的其他任何事情,我会特别指出你指出我指定的mystrcat界面是非常精心设计的,并提供了如何改进它的细节。
Here would be my comments 这是我的评论
const char*
since you have no intention of modifying them. const char*
因为你无意修改它们。 Questions I would have liked you to ask or self answered during the interview 我希望你在面试中问我或自己回答的问题
In addition to the previous answers, one more thing that could go wrong: s3 could point to the middle of s1 or s2 strings. 除了之前的答案,还有一件事可能出错:s3可能指向s1或s2字符串的中间位置。 If this is a legit condition, then you need a bit more sophisticated implementation.
如果这是一个合法的条件,那么你需要更复杂的实现。
There are several criticisms that could be made about your function definition, but within the constraints of the problem statement your function will produce the correct answer. 关于你的函数定义有几个批评,但在问题陈述的约束下你的函数会产生正确的答案。 It isn't technically wrong.
这在技术上并不错误。
My guess is that the problem wasn't effectively communicated, or the interviewer's criticism wasn't effectively communicated. 我的猜测是问题没有得到有效沟通,或者访谈员的批评没有得到有效沟通。 Maybe clarifying these was part of the test, eh?
也许澄清这些是测试的一部分,是吗?
Here's a quick summary of possible complaints... 以下是可能投诉的快速摘要......
This line has a logical error... 这条线有逻辑错误......
if (! (s1 || s2 || s3)) return; if(!(s1 || s2 || s3))返回;
...because it will return if all are null, but you probably want to return if any are null. ...因为它会返回,如果所有都为空,但你可能要返回如果有任何空。 This cannot cause failure because the problem statement says none can be null.
这不会导致失败,因为问题语句说none都不能为null。
A great programmer should strive beyond technical correctness for readability, efficiency, and robust error-handling, but these are mostly subjective and situational. 一个伟大的程序员应该超越技术的正确性,以提高可读性,效率和强大的错误处理能力,但这些主要是主观的和情境性的。 Anyhow, disregarding the error in your first if-statement, I think your function reads well enough and gets the job done.
无论如何,忽略你的第一个if语句中的错误,我认为你的函数读得很好并完成了工作。 :)
:)
invalid check 检查无效
if (! (s1 || s2 || s3)) return; if(!(s1 || s2 || s3))返回; // one/more pointers are invalid
//一个/多个指针无效
It actually checks if at least one pointer is not 0, eg at least one pointer is valid. 它实际上检查至少一个指针是否不为0,例如至少一个指针有效。 It should be
它应该是
if (!s1 || !s2 || !s3) return; if(!s1 ||!s2 ||!s3)返回;
You fail to check if s3 is big enough or if your're writing outside (but the assumption was s3 is big enougn right? - but still it would not work in real worl) 你没有检查s3是否足够大,或者你是否在外面写作(但假设是s3很大的权利? - 但它仍然不适用于真正的世界)
You fail to skip over the null which gets copied from the end of the s1 into s3. 您无法跳过从s1的末尾复制到s3的null。 You attach s2 after 0 in s3 so it will end up "
s1stringvalueNULLs2stringvalue
" (NULL here means value 0 or null or nil in real code, this is for illustration). 你在s3中的0之后附加s2所以它将结束“
s1stringvalueNULLs2stringvalue
”(这里的NULL表示值0或null或实际代码中的nil,这是为了说明)。 Any C method that expects null terminated string will only see the " s1stringvaluepart
" and will stop at null. 任何期望以null结尾的字符串的C方法只会看到“
s1stringvaluepart
”并且将在null处停止。
Here's a solution: 这是一个解决方案:
void mystrcat(char *s1, char *s2, char *s3)
{
if (!s1 || !s2 || !s3) return;
while (*s3++ = *s1++);
if (!*(s3-1)) --s3; // reverse over null in s1
while (*s3++ = *s2++);
*s3 = 0;
}
You can test it with: 你可以测试它:
#include <iostream>
using namespace std;
int main()
{
char s1[] = "short";
char s2[] = "longer";
char s3[20];
memset(s3, 0, sizeof(s3));
mystrcat(0,s2,s3);
cout << "2: " << s3 << endl;
memset(s3, 0, sizeof(s3));
mystrcat(s1,0,s3);
cout << "3: " << s3 << endl;
memset(s3, 0, sizeof(s3));
mystrcat(s1,s2,0);
cout << "4: " << s3 << endl;
memset(s3, 0, sizeof(s3));
mystrcat(s1,s2,s3);
cout << "1: " << s3 << endl;
}
Please correct me if I'm wrong. 如果我错了,请纠正我。 Wouldn't the last character of s3 be '\\0' after copying s1?
复制s1后,s3的最后一个字符不是'\\ 0'吗? So the remaining characters from s2 could never be read in some cases?
那么在某些情况下,s2中的剩余字符永远无法读取?
From my understanding 从我的理解
while(*s3++ = *s1++);
will copy the characters until NULL is reached and '\\0' isn't NULL, or is it treated as such? 将复制字符,直到达到NULL并且'\\ 0'不是NULL,或者它是否被视为? If I can assume that s1 = "Hello" and s2 = " world!"
如果我可以假设s1 =“你好”而s2 =“世界!” then after copying s1, s3 would look like: Hello\\0 and then copying the " world!"
然后在复制s1之后,s3看起来像:Hello \\ 0然后复制“世界!” bit would result in s3 looking like: Hello\\0 world!\\0
bit会导致s3看起来像:Hello \\ 0 world!\\ 0
Does it make any sense? 它有意义吗? Is my understanding correct?
我的理解是否正确?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.