C语言 使用 strcpy 时打印的垃圾



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

法典:

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%sn",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 %dn", (size_t)(pos-temp_str), strlen(key));
g_print("size of the variable "data" = %d or %dn", (size_t)(pos2-pos), strlen(data));
g_print("The key name is %sn",key);
g_print("The value is %sn",data);
g_print("End of Parsern");
  }

输出:

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

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

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

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

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

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

未定义的行为:

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

strcpy的源和目标不得重叠。

您必须记住为字符串分配空间,为终止的"\0"字符添加一个字节。你必须小心strncpy,特别是如果你习惯于使用strcpystrcatsprintf。这三个函数以"\0"终止字符串。 strncpy复制您指定的字节数,并且不假定终止字符串。

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

选择解决一个样本问题的方式略有不同,但它仍然涉及知道我复制的内容的长度。

在这种情况下,我使用 strncpypcszTestStr1和将它们复制到 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%sn", pcszTestStr1);
    strncpy(szTestBuf, pcszTestStr1, 9);
    strcpy(szTestBuf + 9, " much shorter sentence.");
    printf("%sn", 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$ 

相关内容

  • 没有找到相关文章

最新更新