【问题标题】:How to backup strings in C [closed]如何在C中备份字符串[关闭]
【发布时间】:2019-02-04 21:39:50
【问题描述】:

如何以原始形式备份字符串?我正在使用 strncpy() 但是,当我尝试打印句子时,原始文本被改变了。 下面是一个例子:如果我输入“This is a sample text”来获取并要求打印句子,控制台会打印“TTTTs is a ample ttxt”。有人可以告诉如何制作,以便 sentenceBackup 变量具有备份并且句子正确显示为输入。

    //String variable to contain the user input.
    char sentence[] = "";
    char sentenceBackup[] ="";

    //this variable tracks the size of the user input.
    int sentenceLength;

    //ask the user forsinput
    printf("Enter a free formed sentence that needs to be sorted: \n");

    //accept the user entry into sentence.
    //scanf is deprecated since C11.
    gets(sentence);

    // keep a backup for further operation.
    strncpy(sentenceBackup, sentence, findLength(sentence));


    //display the sentence entered.
    printf("The sentence is : %s\n", sentence);

Ps:如果我去掉strncpy()方法,源文本,即句子变量会正确显示。

【问题讨论】:

  • 当您在 C 中声明一个数组而不指定数组大小时,C 假定它的大小与其初始值设定项相同。在你的情况下,1 char long。试着给你的数组声明一个大的尺寸,比如[2048];否则写入sentenceBackup 的第二个字符可能会覆盖sentence 的第一个字符。将数组想象成在内存中相邻并且只有 1 个字符长,每个...strncpy 写入的第二个字符在哪里?
  • char sentence[] = "" 太小,无法接收来自 gets(sentence); 的输入
  • 为什么评论scanf is deprecated in C11?它不是(参见n1570 的§7.21.6.4)。当然 gets 不存在于 C11 中(在 §7.21.7.2 中有 fgets)所以你应该 not 使用它。请编辑您的问题以改进它!
  • 顺便说一句,你的问题没有minimal reproducible example。它应该有一个完整的程序。这是改善您的问题的另一个原因

标签: c string pointers c-strings strcpy


【解决方案1】:
  1. sentence 的大小不足以容纳输入。

  2. 其次,gets 已弃用,所以不要使用它。来自这个online C reference

    gets() 函数不执行边界检查,因此该函数极易受到缓冲区溢出攻击。它不能安全使用(除非程序在限制标准输入上出现的内容的环境中运行)。出于这个原因,该功能已在 C99 标准的第三次勘误中被弃用,并在 C11 标准中完全删除。 fgets() 和 gets_s() 是推荐的替代品。 永远不要使用gets()。

【讨论】:

  • C11 标准n1570 甚至没有提及 gets
  • @BasileStarynkevitch: N1570: footnote 404 (Annex K.3.5.4.1: gets_s 函数,与历史上的 gets 函数不同,...... 另外,在文档的另一端,Foreword §6删除了 gets 函数 (<stdio.h>) 但我承认,这些并不是主要的参考,当然也不是古老的 gets() 函数的定义。
  • 而n1570的索引别提gets
【解决方案2】:

如果您可以接受using getlinestrdup,请使用它们!

如果你不允许使用它们,你至少应该heap-allocate 字符串(使用calloc,但不要忘记结束 NUL 字节的额外字节)并且不要以后别忘了free他们。当然,您需要明确地“备份”(通过适当地复制原始字符串)。

如果不允许堆分配,请务必声明足够大的缓冲区。我建议至少 128 字节。

请查看一些C reference 站点(研究您使用的每个函数的文档),然后参考C11 标准n1570。您会看到 gets 不再是 C 的一部分,并且由于危险而被禁止。至少使用fgets(最好使用getline)。

使用所有警告和调试信息编译您的代码,例如gcc -Wall -Wextra -gGCC。改进它以完全没有警告。使用调试器(gdb 或其他东西)并阅读How To Debug Small Programs

请注意,UTF-8 is used everywhere 在 2018 年。因此,strlen 不提供字符数(因为像 Ê 这样的字符需要 UTF-8 中的多个字节),只提供字节长度。

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2016-07-24
    • 2012-12-11
    • 2020-10-16
    • 2016-12-12
    • 2014-03-17
    相关资源
    最近更新 更多