链表创建输入和打印出现乱码

在VS2022中创建了一个链表,但是测试时发现输入数据次数不对而且输出是是乱码,但是已经验证相同写法的另一链表存入数据和打印都正常,这是什么原因呢?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
struct app
{
    char gender;
    int agemin;
    int agemax;
    long incomemin;
    long incomemax;
    struct app* next;
};
int main()
{
    int i, m;
    scanf("%d", &m);
    struct app* ahead = NULL;
    struct app* acur;
    struct app* aprev = NULL;
    for (i = 0; i < m; i++)
    {
        acur = (struct app*)malloc(sizeof(struct app));
        if (ahead == NULL)
            ahead = acur;
        else
            aprev->next = acur;
        acur->next = NULL;
        scanf("%c %d %d %ld %ld", &(acur->gender), &(acur->agemin), &(acur->agemax), &(acur->incomemin), &(acur->incomemax));        
        aprev = acur;
    }
    acur = ahead;
    for (i = 0; i < m; i++)
    {
        printf("%c %d %d %ld %ld", acur->gender, acur->agemin, acur->agemax, acur->incomemin, acur->incomemax);
        acur = acur->next;
        printf("\n");
    }
    acur = ahead;
    while (acur != NULL)
    {
        acur = ahead;
        ahead = acur->next;
        free(acur);
        acur = acur->next;
    }
    return 0;
}


下面是运行结果

img

这不是乱码,数据未正确被赋值,程序打印了未知的数据

原因是 你的 %c 接受了 换行符,导致后续的数据接收都有问题

先看截图:

img

改造如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
struct app
{
    char gender;
    int agemin;
    int agemax;
    long incomemin;
    long incomemax;
    struct app* next;
};
int main()
{
    int i, m;
    scanf("%d", &m);
    struct app* ahead = NULL;
    struct app* acur;
    struct app* aprev = NULL;
    for (i = 0; i < m; i++)
    {
        acur = (struct app*)malloc(sizeof(struct app));
        if (ahead == NULL)
            ahead = acur;
        else
            aprev->next = acur;
        acur->next = NULL;
        getchar(); // 接收一下换行符
        scanf("%c %d %d %ld %ld", &(acur->gender), &(acur->agemin), &(acur->agemax), &(acur->incomemin), &(acur->incomemax));        
        aprev = acur;
    }
    acur = ahead;
    for (i = 0; i < m; i++)
    {
        printf("%c %d %d %ld %ld", acur->gender, acur->agemin, acur->agemax, acur->incomemin, acur->incomemax);
        acur = acur->next;
        printf("\n");
    }
    acur = ahead;
    while (acur != NULL)
    {
        acur = ahead;
        ahead = acur->next;
        free(acur);
        acur = acur->next;
    }
    return 0;
}

代码里第28行:scanf("%c %d %d %ld %ld", &(acur->gender), &(acur->agemin), &(acur->agemax), &(acur->incomemin), &(acur->incomemax));
在格式控制符 %c 前留一个空格:scanf(" %c %d %d %ld %ld", &(acur->gender), &(acur->agemin), &(acur->agemax), &(acur->incomemin), &(acur->incomemax)); 就可以了。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7717444
  • 你也可以参考下这篇文章:字符串左旋 & 判断一个字符串是否为另外一个字符串旋转之后的字符串
  • 除此之外, 这篇博客: 大小端介绍,你知道常用的VS2019内存中字节序存储的顺序吗?中的 一、引入大小端 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    在我们经常使用的VS2019编译器使用过程过,我们经常会查看变量的内存

    例如

    int main()
    {
    	int a = 10;
    	int b = -10;
    
    	return 0;
    }

     内存: 0x00 00 00 0a

    我们观察编译器中的字节序

     内存:0xff ff ff f6

    编译器中的字节序:

    我们再看一个:

    int main()
    {
    	int a = 0x11223344;
    
    	return 0;
    }

     

    我们发现编译器中的存储方式与我们写出来的地址存储的顺序相反,怎么解释这种现象呢?我们就引入了大小端存储。

  • 以下回答来自chatgpt:

    问题原因是在输入字符串时,使用了gets函数。然而,gets函数存在安全性问题,容易产生缓冲区溢出,因此在新的编译器中被移除了。

    建议使用安全的输入函数scanf或fgets来替代gets函数:

    char s[3][20],temp[20],filename[20];
    int i,j,k;
    
    for(i=0;i<3;i++){
        printf("请输入第%d个字符串: ",i+1);
        fgets(s[i], sizeof(s[i]), stdin);
        // 去除换行符
        s[i][strlen(s[i])-1] = '\0';
    }
    

    之后的排序和输出部分没有问题,可以继续使用原有的代码。

    另外,需要注意的是,在使用scanf函数输入字符串时,要确保输入的字符串长度不超过指定的数组长度,避免产生缓冲区溢出。可以使用格式限定符"%ns"来指定字符串的最大长度。

    printf("请输入磁盘文件名:");
    scanf("%19s",filename);
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^