【问题标题】:strncpy and strcat usagestrncpy 和 strcat 用法
【发布时间】:2016-02-10 21:36:38
【问题描述】:

我的作业要求显示我的名字,使其看起来像这样:'姓氏,名字'。姓氏,然后 [逗号空格] 名字。虽然没有移过该名称之后的其余文本。这是我的代码:

  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 = last name, fn = first name 我为 ', ' 逗号空间创建了 str2。

他要我做什么?

【问题讨论】:

  • ln和fn有哪些类型?为什么不能直接使用它们?
  • 你必须使用strcpystrncat吗?如果没有,请查看sprintf
  • 它们是 char[size]。
  • 您不需要为最终字符串分配 3 个单独的缓冲区。您可以只分配一个缓冲区,然后将 strcat 字符串分配给它。例如strcat(str1, ", ");。或者,您可以使用 sprintf。
  • 另外,您应该确保 str1 的大小正确。 str1 是 11 个字节,但您调用 strncat 时将 31 个字节作为最大长度参数。来自 Linux 手册页:“dest 的大小必须至少为 strlen(dest)+n+1”

标签: c string syntax


【解决方案1】:

我很惊讶你的导师接受了你的回答。您将结果累积在 char 数组 str1 中,您已声明该数组只有 11 个字符。除非strlen(ln)+strlen(fn)<=8,否则将溢出为结果str1 分配的空间。在过去糟糕的日子里,C 程序员会简单地分配一个看起来足够大的结果数组,而不必费心检查。 stdio.h 中的标准 C 库函数 sprintf 就是为这项工作而设计的:

#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);

您还可以使用strcpy/strcat 系列函数,它们位于string.h 中。 (这是在您的作业中指定的吗?)安全、现代的等价物是 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);

strncpy 调用很危险,因为它可能不会在 result 中留下以 null 结尾的字符串,这将导致后续的 strcat 失败。这并不比您所做的少多少行,但是仅使用这些 string.h 函数,很难做得更好并保证无论给出什么 lnfn 都不会溢出结果缓冲区.

【讨论】:

    【解决方案2】:

    假设你知道字符串的长度,为什么不知道

    char result[50];
    
    sprintf(result,"%s, %s",ln, fn);
    

    【讨论】:

      【解决方案3】:
      char result[50];
      
      strcpy(result, ln);
      strcat(result, ", ");
      strcat(result, 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 个字符的数组可能不够用。

        【讨论】:

          【解决方案5】:

          您的strcpy 调用实际上是不必要的,因为您已经在变量中拥有名字和姓氏。您可以创建一个足够大的缓冲区来容纳整个字符串,然后使用strcat 创建最终的“姓氏,名字”字符串。

          【讨论】:

            猜你喜欢
            • 2016-03-03
            • 1970-01-01
            • 2013-10-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-21
            • 1970-01-01
            • 2011-06-03
            相关资源
            最近更新 更多