为什么 strcpy 将垃圾字符附加到一小部分字符串的末尾?
Why is strcpy appending junk characters to the end of a small fraction of strings?
我有一个函数将包含 hyperlink 的字符串作为其输入并尝试输出相同的 hyperlink 除非它包含问号,该字符和任何它后面的字符被清除。
首先,我打开一个文本文件并读入包含 link 且仅包含 link 的行,如下所示:
FILE * ifp = fopen(raw_links,"r");
char link_to_filter[200];
if(ifp == NULL)
{
printf("Could not open %s for writing\n", raw_links);
exit(0);
}
while(fscanf(ifp,"%s", link_to_filter) == 1)
{
add_link(a,link_to_filter, link_under_wget);
};
fclose(ifp);
add_link 所做的部分工作是在问号后删除 link 中不必要的部分(如 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/online-giving/step1.php?new=1)导致我对 wget 的调用出现问题。它通过此函数 remove_extra 馈送 link_to_filter 来完成此操作,如下所示。
char * remove_extra(char * url)
{
char * test = url;
int total_size;
test = strchr(url,'?');
if (test != NULL)
{
total_size = test-url;
url[total_size] = '[=11=]';
}
return url;
}
在 remove_extra 的末尾,从 remove_extra 返回后,在使用 strcpy 之前立即调用 printf,就像这样
printf("%s",url);
将打印出我期望看到的内容(例如 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/online-giving/step1.php 不带“?”或尾随字符),但在此代码块运行后立即
struct node * temp = (struct node *)malloc(sizeof(struct node));
char * new_link = remove_extra(url);
temp->hyperlink =(char *)malloc(strlen(new_link) * sizeof(char));
strncpy(temp->hyperlink, new_link, strlen(new_link));
成员 hyperlink 上的 printf 的结果偶尔在末尾有一个垃圾字符(有时 'A' 或 'Q' 或 '!',但始终相同对应于同一字符串的字符)。如果每个 link 或特定类型的 link 都发生这种情况,我可以想出办法,
但它可能每 20 次 link 发生一次,并且它恰好发生在 link 短和长。
例如
xxxxxxxxxxxxxxxxxxxx/hr/ --> xxxxxxxxxxxxxxxxxxxx/hr/!
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/windows-to-the-past/ --> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/windows-to-the-past/Q
strcpy 和自制字符串复制循环都会发生这种情况,所以我倾向于认为这不是 strcpy 的错,但我想不出错误还会出在哪里。
很可能您忘记在字符串末尾复制一个空终止符,请记住 strlen(str) 给出了可见字符的数量,您还需要在末尾添加“\0”。
你需要做
temp->hyperlink =(char *)malloc(strlen(new_link)+1);//char is one byte, sizeof(char)=1
和
strcpy(temp->hyperlink, new_link);
应该可以正常工作。
为什么不使用 strdup
?
如果您将 len
计算为 src
的长度,那么 strncpy
的天真用法——尽管它可能很诱人——是不正确的:
size_t len = strlen(src);
dest = malloc(len); /* DON'T DO THIS */
strncpy(dest, src, len); /* DON'T DO THIS, EITHER */
strncpy
正好复制 len
个字节;它确实 not 保证在末尾放置一个 NUL 字节。由于 len
恰好是 src
的长度,因此 src
的前 len
字节中没有 NUL 字节,并且不会插入 NUL
字节strncpy
.
如果您使用 strcpy
代替(应该是 "unsafe" 接口):
strcpy(dest, src);
本来还可以,只是dest
不够大。你真正需要做的是:
dest = malloc(strlen(src) + 1); /* Note: include space for the NUL */
strcpy(dest, src);
或者,如果您有有用的 strdup
功能:
dest = strdup(src);
我有一个函数将包含 hyperlink 的字符串作为其输入并尝试输出相同的 hyperlink 除非它包含问号,该字符和任何它后面的字符被清除。
首先,我打开一个文本文件并读入包含 link 且仅包含 link 的行,如下所示:
FILE * ifp = fopen(raw_links,"r");
char link_to_filter[200];
if(ifp == NULL)
{
printf("Could not open %s for writing\n", raw_links);
exit(0);
}
while(fscanf(ifp,"%s", link_to_filter) == 1)
{
add_link(a,link_to_filter, link_under_wget);
};
fclose(ifp);
add_link 所做的部分工作是在问号后删除 link 中不必要的部分(如 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/online-giving/step1.php?new=1)导致我对 wget 的调用出现问题。它通过此函数 remove_extra 馈送 link_to_filter 来完成此操作,如下所示。
char * remove_extra(char * url)
{
char * test = url;
int total_size;
test = strchr(url,'?');
if (test != NULL)
{
total_size = test-url;
url[total_size] = '[=11=]';
}
return url;
}
在 remove_extra 的末尾,从 remove_extra 返回后,在使用 strcpy 之前立即调用 printf,就像这样
printf("%s",url);
将打印出我期望看到的内容(例如 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/online-giving/step1.php 不带“?”或尾随字符),但在此代码块运行后立即
struct node * temp = (struct node *)malloc(sizeof(struct node));
char * new_link = remove_extra(url);
temp->hyperlink =(char *)malloc(strlen(new_link) * sizeof(char));
strncpy(temp->hyperlink, new_link, strlen(new_link));
成员 hyperlink 上的 printf 的结果偶尔在末尾有一个垃圾字符(有时 'A' 或 'Q' 或 '!',但始终相同对应于同一字符串的字符)。如果每个 link 或特定类型的 link 都发生这种情况,我可以想出办法, 但它可能每 20 次 link 发生一次,并且它恰好发生在 link 短和长。
例如 xxxxxxxxxxxxxxxxxxxx/hr/ --> xxxxxxxxxxxxxxxxxxxx/hr/!
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/windows-to-the-past/ --> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/windows-to-the-past/Q
strcpy 和自制字符串复制循环都会发生这种情况,所以我倾向于认为这不是 strcpy 的错,但我想不出错误还会出在哪里。
很可能您忘记在字符串末尾复制一个空终止符,请记住 strlen(str) 给出了可见字符的数量,您还需要在末尾添加“\0”。 你需要做
temp->hyperlink =(char *)malloc(strlen(new_link)+1);//char is one byte, sizeof(char)=1
和
strcpy(temp->hyperlink, new_link);
应该可以正常工作。
为什么不使用 strdup
?
如果您将 len
计算为 src
的长度,那么 strncpy
的天真用法——尽管它可能很诱人——是不正确的:
size_t len = strlen(src);
dest = malloc(len); /* DON'T DO THIS */
strncpy(dest, src, len); /* DON'T DO THIS, EITHER */
strncpy
正好复制 len
个字节;它确实 not 保证在末尾放置一个 NUL 字节。由于 len
恰好是 src
的长度,因此 src
的前 len
字节中没有 NUL 字节,并且不会插入 NUL
字节strncpy
.
如果您使用 strcpy
代替(应该是 "unsafe" 接口):
strcpy(dest, src);
本来还可以,只是dest
不够大。你真正需要做的是:
dest = malloc(strlen(src) + 1); /* Note: include space for the NUL */
strcpy(dest, src);
或者,如果您有有用的 strdup
功能:
dest = strdup(src);