【问题标题】:Garbage being printed when using strcpy使用 strcpy 时打印垃圾
【发布时间】:2012-06-22 17:55:22
【问题描述】:

我有一个函数可以解析一些传入的数据。我的问题是使用 strncpy 后,当我尝试打印它时会得到一些垃圾。我尝试使用 malloc 使 char 数组具有确切的大小。

代码:

void parse_data(char *unparsed_data)
{
char *temp_str;
char *pos;
char *pos2;
char *key;
char *data;
const char newline = '\n';

int timestamp = 0;

temp_str = (char*)malloc(strlen(unparsed_data));

g_print("\nThe original string is: \n%s\n",unparsed_data);


//Ignore the first two lines
pos = strchr(unparsed_data, newline);
strcpy(temp_str, pos+1);
pos = strchr(temp_str, newline);
strcpy(temp_str, pos+1);

//Split the line in two; The key name and the value
pos = strchr(temp_str, ':'); // ':' divides the name from the value
pos2 = strchr(temp_str, '\n'); //end of the line
key = (char*)malloc((size_t)(pos-temp_str)-1); //allocate enough memory
data = (char*)malloc((size_t)(pos2-pos)-1);

strncpy(key, temp_str, (size_t)(pos-temp_str));
strncpy(data, pos + 2, (size_t)(pos2-pos));

timestamp = atoi(data);

g_print("size of the variable \"key\" = %d or %d\n", (size_t)(pos-temp_str), strlen(key));
g_print("size of the variable \"data\" = %d or %d\n", (size_t)(pos2-pos), strlen(data));

g_print("The key name is %s\n",key);
g_print("The value is %s\n",data);
g_print("End of Parser\n");
  }

输出:

The original string is: 
NEW_DATAa_PACKET
Local Data Set 16-byte Universal Key
Time Stamp (microsec): 1319639501097446
Frame Number: 0
Version: 3
Angle (deg): 10.228428

size of the variable "key" = 21 or 22
size of the variable "data" = 18 or 21
The key name is Time Stamp (microsec)
The value is 1319639501097446
F32
End of Parser

再次运行:

  The original string is: 
  NEW_DATAa_PACKET
  Local Data Set 16-byte Universal Key
  Time Stamp (microsec): 1319639501097446
  Frame Number: 0
  Version: 3
  Angle (deg): 10.228428

  size of the variable "key" = 21 or 25
  size of the variable "data" = 18 or 18
  The key name is Time Stamp (microsec)ipe 
  The value is 1319639501097446
  F
  End of Parser

【问题讨论】:

    标签: c parsing text malloc strncpy


    【解决方案1】:

    您的结果是因为strncpy 没有在字符串末尾放置空字符。

    【讨论】:

      【解决方案2】:

      您的strncpy(data, pos + 2, (size_t)(pos2-pos)); 不会在字符串末尾添加终止\0 字符。因此,当您稍后尝试打印它时,printf() 会打印您的整个数据字符串以及紧随其后的内存中的任何内容,直到它达到零 - 这就是您得到的垃圾。您需要在数据末尾显式附加零。 atoi() 也需要它。

      编辑: 您需要为您的data 再分配一个字节,并在那里写一个终止字符。 data[len_of_data] = '\0'。只有在此之后,它才成为有效的 C 字符串,您可以将其用于 atoi()printf()

      【讨论】:

      • 感谢您的回复。我将如何在末尾添加终止字符?
      • 基本上你需要为你的data再分配一个字节,并在那里写一个终止字符。 data[len_of_data] = '\0'。只有在那之后它才成为一个 C 字符串,你可以将它用于atoi()printf()
      【解决方案3】:

      你需要 malloc() +1 字节的字符串,所以当你执行 strcpy() 时它可以附加零,但 strncpy 不会附加零,因为你需要一个额外的字节。

      【讨论】:

        【解决方案4】:

        一个问题:如果没有换行符怎么办?

        未定义的行为:

        pos = strchr(temp_str, newline);
        strcpy(temp_str, pos+1);
        

        strcpy 的源和目标不能重叠。

        【讨论】:

          【解决方案5】:

          您必须记住在为字符串分配空间时为终止字符“\0”添加一个字节。您必须小心使用strncpy,尤其是如果您习惯使用strcpystrcatsprintf。这三个函数用 '\0' 终止字符串。 strncpy 复制您指定的多个字节,并且不假设终止字符串。

          您通过确保在复制到的字符缓冲区的末尾放置一个“\0”来承担该责任。这意味着您必须知道副本的起始位置和长度,并在起始位置和长度之和的后面加上一个 '\0' 字节。

          我选择解决示例问题的方式略有不同,但它仍然涉及了解我复制的内容的长度。

          在这种情况下,我使用 strncpypcszTestStr1 中获取前 9 个字符,然后 将它们复制到 szTestBuf。然后,我使用 strcpy -- 它以零结束字符串 -- 追加句子的新部分。

          #include <stdio.h>
          #include <string.h>
          
          int n;
          int argv_2;
          
          char szTestBuf[100] = {0};
          char * pcszTestStr1 = 
          "This is a very long, long string to be used in a C example, OK?";
          
          int main(int argc, char *argv[])
          {
              int rc = 0;
          
              printf("The following sentence is too long.\n%s\n", pcszTestStr1);
              strncpy(szTestBuf, pcszTestStr1, 9);
              strcpy(szTestBuf + 9, " much shorter sentence.");
              printf("%s\n", szTestBuf); 
          
              return rc;
          }
          

          这是运行 test.c 的输出编译 gcc -o test test.c

          cnorton@hiawatha:~/scratch$ ./test
          The following sentence is too long.
          This is a very long, long string to be used in a C example, OK?
          This is a much shorter sentence.
          cnorton@hiawatha:~/scratch$ 
          

          【讨论】:

            猜你喜欢
            • 2017-07-21
            • 1970-01-01
            • 2015-08-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-14
            • 2013-12-23
            • 1970-01-01
            相关资源
            最近更新 更多