strncpy和strcat的用法

4

我的作业要求将我的名字显示为这样:'Lastname, Firstname'。姓氏在前,然后是[逗号空格]名字。同时不要移动该名称后面的其他文本。这是我的代码:

  char str1[11];
  char str2[3];
  char str3[16];
  strcpy (str1,fn);
  strcpy (str2,", ");
  strcpy (str3,ln);
  strncat (str1, str2, 14);
  strncat (str1, str3, 31);

我的老师说我完成了他要求的任务,但是他不喜欢我使用的代码行数,并表示我做了多余的工作。

变量:ln = 姓fn = 名。我为逗号和空格创建了 str2。

他想让我做什么?


ln和fn是什么类型?为什么不能直接使用它们? - jeff carey
如果不需要使用 strcpystrncat,那么可以了解一下 sprintf - tonysdg
它们是char[size]。 - GeekyDewd
2
你不需要为最终字符串分配3个单独的缓冲区。你只需分配一个单一的缓冲区,然后将字符串连接起来。例如:strcat(str1, ", ");。或者,你可以使用sprintf。 - Bobby Sacamano
2
此外,您应确保str1的大小正确。 str1为11个字节,但您正在使用31个字节作为max length参数调用strncat。来自Linux man页面:“dest的大小必须至少为strlen(dest)+ n + 1”。 - Bobby Sacamano
5个回答

6
假设您已经知道字符串的长度,为什么不这样做:
char result[50];

sprintf(result,"%s, %s",ln, fn);

4
这是你所需要的全部内容:
strcpy (str1,ln);    // Copy the last name to str1
strcat (str1,", ");  // Now append ", " to the last name in str1
strcat (str1,fn);    // Lastly, append the first name to str1

您必须确保str1足够大来容纳所有内容。一个长度为13的字符数组可能不足以容纳。


4
char result[50];

strcpy(result, ln);
strcat(result, ", ");
strcat(result, fn);

他是对的,你使用了太多的语句(并浪费了太多内存)。

1
我很惊讶你的教练接受了你的答案。你将结果累积在字符数组str1中,而你声明它只有11个字符。除非strlen(ln)+strlen(fn)<=8,否则你会溢出为结果分配的空间str1。在过去不好的日子里,C程序员会简单地分配一个似乎足够大的结果数组,并且不费心检查。标准的C库函数sprintf在stdio.h中专门用于此任务。
#include <stdio.h>
...fn, ln defined...
char result[80];  /* 80 characters is probably enough */
sprintf(result, "%s, %s", ln, fn);

现代C程序员永远不会假设lnfn的长度足够短,不会导致结果数组溢出。安全、现代的替代方法将sprintf调用替换为snprintf
snprintf(result, 80, "%s, %s", ln, fn);

你还可以使用string.h中的strcpy/strcat函数族。这在你的任务要求中有明确说明吗?现代安全的等效函数是strncpystrncat,它们允许你指定要复制的最大字符数。使用这些函数的一种快速而安全的解决方案是:
char result[80];
result[0] = '\0';     /* initialize result to "" */
strncat(result, ln, 40);
strcat(result, ", ")  /* you know this adds exactly two characters */
strncat(result, fn, 38);
< p > strncpy 调用是危险的,因为它可能不会在 result 中留下以 null 结尾的字符串,这将导致后续的 strcat 失败。虽然这比您所做的代码行数少得多,但仅使用这些 string.h 函数,要保证无论给定的 lnfn 是什么,都无法溢出结果缓冲区,这很困难。 < / p >

1
你已经有名字和姓氏的变量了,所以你的strcpy调用是不必要的。你可以创建一个足够大的缓冲区来容纳整个字符串,然后使用strcat来创建最终的“姓, 名”字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接