在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;
}
下面是运行结果
这不是乱码,数据未正确被赋值,程序打印了未知的数据
原因是 你的 %c 接受了 换行符,导致后续的数据接收都有问题
先看截图:
改造如下:
#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)); 就可以了。
在我们经常使用的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;
}
我们发现编译器中的存储方式与我们写出来的地址存储的顺序相反,怎么解释这种现象呢?我们就引入了大小端存储。
问题原因是在输入字符串时,使用了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);