【问题标题】:garbage characters while inserting string to a linked list in c将字符串插入到c中的链表时出现垃圾字符
【发布时间】:2017-02-02 19:38:19
【问题描述】:

所以,我试图用这个来实现,是创建一个包含三个字符串作为数据的链表。输出显示了预期的字符串,但添加了一些垃圾符号,例如:预期的“string pierwszy”,得到:“string pierwszyn~rŚÝ”。

我也尝试打印出strlen(tmp->word),结果是3。我不明白,我以为是1。我不明白,为什么会这样。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct element element;

struct element{
    char * word;
    element * next;
};

element * head = NULL;

void addWord(char * new_word){
    printf("new_word: %s\n\n\n", new_word);

    element *tmp = NULL;
    tmp = malloc(sizeof(element));

    element *current = head;

    tmp->word = malloc(sizeof(char) * strlen(new_word)+1);
    strncpy(tmp->word, new_word, strlen(new_word));
    tmp->word[strlen(new_word)] = "\0";

    tmp->next = current;
    head = tmp;

}
void free_list(element * node){
    if(node != NULL){
        free_list(node->next);
        free(node->word);
        free(node);
    }
}
void print_list(element * node){
    element * tmp = node;
    while(tmp != NULL){
        printf("word: %s\n", tmp->word);
        tmp = tmp->next;
    }
}
int main()
{
    char * name1 = "string pierwszy";
    char * name2 = "drugi";
    char * name3 = "333trzeci";

    addWord(name1);
    addWord(name2);
    addWord(name3);
    print_list(head);

    free_list(head);
    return 0;
}

【问题讨论】:

  • man strncpy: [...]strncpy()函数类似,只不过最多复制n个字节的src。警告:如果 src 的前 n 个字节中没有空字节,则放在 dest 中的字符串不会以空值结尾。[...]
  • 以下代码 tmp-&gt;word[strlen(new_word)] = "\0"; 无法编译。将"\0";(字符串)替换为'\0'(空终止符)。

标签: c string linked-list insert character


【解决方案1】:

问题出在下面一行:

tmp->word[strlen(new_word)] = "\0";

"\0"'\0' 之间存在差异。 '\0' 在这种情况下是正确的,因为它只是一个空字符。 "\0" 是一个包含空字符的字符串,因此它与
{'\0', '\0'} 完全相同(您输入的一个空字符,一个自动添加的空字符)。

由于出于某些目的将 C 中的数组视为指针,因此您编写的代码在内存中创建了一个包含两个空字符的数组,获取第一个元素的地址,使用 @987654321 将其转换为 char @ 并将其存储在字符串中。所以你所做的基本上等同于这样做:

char someString[2];
someString[0] = '\0';
someString[1] = '\0';
tmp->word[strlen(new_word)] = (char)&(someString[0]);

由于字符串没有任何终止的空字符,因此它不知道字符串的结束位置,因此它会继续几个字符,为您提供恰好在内存中的字符。

所以你说的第一个“垃圾”字符是某个字符串的地址的 ASCII 等价物,而其他的则是当时恰好在内存中的内容。

正确的代码当然如下:

tmp->word[strlen(new_word)] = '\0';

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 2015-01-28
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多