【问题标题】:why won't %s print from a linked list [duplicate]为什么 %s 不能从链表中打印 [重复]
【发布时间】:2020-04-20 14:28:44
【问题描述】:

我创建了一个包含 char 数组的链表。然后我尝试使用 %s 打印它,它不会打印。我知道我必须通过添加“\0”来转换字符,以便它可以使用“/0”打印。但我不知道为什么。

例如,如果我输入:

鲍勃 20

应该打印出来:

新创建的学生:Bob 20 岁。

但是:它正在打印(没有“Bob”):

新创建的学生:20 岁。

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

struct student {
      char name[50];
      int age;
      struct student *next;
};


struct student *createStudent(char studentName[], int studentAge);

int main(void) {
    struct student *studptr;
    int myAge;
    char myName[50];
    scanf("%s %d", myName, &myAge);
    studptr = createStudent(myName, myAge);
    printf("New student created: %s is %d years old.\n", studptr->name, studptr->age);
    free(studptr);
    return 0;
}

struct student *createStudent(char studentName[], int studentAge){

    struct student * ptr;
    ptr = (struct student *)malloc(sizeof(struct student));

    ptr->name[50] = studentName[50];
    ptr->age = studentAge;
    ptr->next = NULL;

    return ptr;
}

注意:我知道下面的代码可以工作并打印正确的名称,我在其中添加了一个额外的方法来更改名为 copyStr() 的 char 数组,但我不确定为什么......

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

struct student {
      char name[50];
      int age;
      struct student *next;
};


struct student *createStudent(char studentName[], int studentAge);
void copyStr(char *source, char *target);

int main(void) {
    struct student *studptr;
    int myAge;
    char myName[50];
    scanf("%s %d", myName, &myAge);
    studptr = createStudent(myName, myAge);
    printf("New student created: %s is %d years old.\n", studptr->name, studptr->age);
    free(studptr);
    return 0;
}

struct student *createStudent(char studentName[], int studentAge){

    struct student * ptr;
    ptr = (struct student *)malloc(sizeof(struct student));

    //we need to translate the char into a string
    copyStr(studentName, ptr->name);


    ptr->name[50] = studentName[50];
    ptr->age = studentAge;
    ptr->next = NULL;

    return ptr;
}

void copyStr(char *source, char *target){

    int i = 0;
    while(source[i] != '\0')
    {
        target[i] = source[i];
        i++;
    }
    target[i] = '\0';
}

【问题讨论】:

  • ptr-&gt;name[50] = studentName[50]; 这不是您在 C 中复制数组的方式;复制单个字符。更糟糕的是,这会通过访问超出声明大小的数组来调用 未定义的行为。 (两者都是char[50],因此只能从 0..49 开始索引)。
  • 您正在复制字符,这也超出了限制ptr-&gt;name[50] = studentName[50] + 使用strcpy 而不是某些复制功能
  • 请参阅How to copy a char array in C?,了解为什么复制字符串需要循环。
  • copyStr 函数是不必要的。标准库已经有strcpy

标签: c linked-list singly-linked-list c-strings strcpy


【解决方案1】:

数组没有赋值运算符。

此声明

ptr->name[50] = studentName[50];

尝试将指针studentName指向的数组的索引为50的不存在的元素分配给数组ptr->name的不存在的元素。

您应该使用在标头&lt;string.h&gt; 中声明的标准C 函数strcpy

例如

strcpy( ptr->name, studentName );

【讨论】:

    【解决方案2】:

    添加到@Vlad 的答案,复制数组的正确方法是遍历它们,从而选择 char 数组中的每个元素并将其复制到新位置。 strncpy 与缓冲区溢出检查完全一样,这使它比 strcpy 更好。

    请查看strcpy 文档,其中说:“确保目标指向的数组的大小应足够长,以包含与源相同的 C 字符串(包括终止空字符),并且不应在内存与源"

    在完全不同的旁注中,如果您正在寻找单行作业,则可以这样做:

       char sample[] = {"randomText"};
       char sample2[11] = {"randomText"};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多