[英]Why does my program keep printing garbage values?
由于某些原因,当我输入时间,描述和索引并单击退出以打印我已使用值和字符串填充的数组时,我会得到一堆打印出来的垃圾值,而不是我输入的内容,不确定我在做什么错。 有什么建议吗?
由于某些原因,当我输入时间,描述和索引并单击退出以打印我已使用值和字符串填充的数组时,我会得到一堆打印出来的垃圾值,而不是我输入的内容,不确定我在做什么错。 有什么建议吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
struct event //data type called event which holds time and description for events
{
int hour; //holds the hour digit between 0-23
int minute; //holds the minute digit between 0-59
char description[41];
//holds the description for the reason of the alarm
};
typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"
int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
int AddEventAtIndex(Event list[], Event e, int i);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);
int main (void)
{
Event EventList[MAX];
Event e;
int i=0;
int eventListSize = 0;
int choice;
do
{
printf("__= Scheduler v1.0 =__\n");
printf("1. Schedule an event.\n");
printf("2. Delete an event.\n");
printf("3. Display schedule.\n");
printf("4. Save schedule.\n");
printf("5. Load schedule.\n");
printf("6. Exit\n");
switch(choice = InputRange(1, 6))
{
case 1: InputEvent( EventList );
i = AddEventAtIndex(EventList, e, i);
break;
/* case 2: pHead = deleteStudent(pHead);
break;
case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
scanf("%d", &search);
if (search == 1){
searchStudentID(pHead);
}
else if (search == 2){
searchStudentlName(pHead);
}
else{
printf("Invalid selection");
}
break;
case 4: displayStudentInfo(pHead);
break;
case 5: saveStudentInfo(pHead);
break;
case 6: end(pHead);
break;*/
default: printf("Exiting Program\n\n");
}
}
while ( choice != 6 );
printf("Index #[]\tTime\tDescription");
for ( int j = 1; j < 6; j++)
{
printf("\n[%d]\n\t%d:%d \t %s", j, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
}
int InputRange(int min, int max)
{
int timenumber;
printf("Please enter a number between %d - %d\n", min, max);
scanf("%d", &timenumber);
printf("\n");
if (timenumber < min || timenumber > max)
{
printf("Invalid Entry\n");
InputRange(min, max);
}
return timenumber;
}
Event* InputEvent(Event *newEvent)
{
if (newEvent != NULL) // quality assurance:
// make sure the pointer is valid
{
printf("Enter the event time:\n");
newEvent->hour = InputRange(0, 23);
newEvent->minute = InputRange(0, 59);
printf("Enter the event description:\n");
fgetc(stdin);
fgets(newEvent->description, 41, stdin);
printf("\n");
}
return newEvent;
}
int AddEventAtIndex(Event list[], Event e, int i)
{
--i;
printf("Where in the array would you like to store this event\n");
i = InputRange(1, 5);
list[i].hour = e.hour;
list[i].minute = e.minute;
strcpy(list[i].description, e.description);
return i;
}
为什么我的程序会继续打印垃圾值?
您使用未初始化的数据, 主要是:
Event e; ... i = AddEventAtIndex(EventList, e, i);
其中e未初始化但在AddEventAtIndex中使用 :
int AddEventAtIndex(Event list[], Event e, int i) { ... list[i].hour = e.hour; list[i].minute = e.minute; strcpy(list[i].description, e.description);
具有未初始化值的strcpy的行为是不确定的,并且可能会产生严重的后果。
可能调用InputEvent( EventList );
必须由InputEvent(&e);
代替InputEvent(&e);
在
for ( int j = 1 ; j < 6 ; j++) { printf("\\n[%d]\\n\\t%d:%d \\t %s", j, EventList[j].hour, EventList[j].minute, EventList[j].description); }
当j为5和6时,您可以从EventList中访问,例如:
for ( int j = 0 ; j < MAX ; j++)
{
printf("[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
但是,您也要写出从未设置打印“垃圾值”的条目,更多的情况是打印未初始化的字符串会产生不确定的影响。 分开设置和不设置条目的一种方法是将所有小时数初始化为24,然后在循环中测试该值是否写入条目。
我还更改了格式,因为索引后的换行符与printf("Index #[]\\tTime\\tDescription");
不兼容printf("Index #[]\\tTime\\tDescription");
并且,最好是把其他换行之后的所有而不是之前刷新输出线,因此也改变printf("Index #[]\\tTime\\tDescription");
通过puts("Index #[]\\tTime\\tDescription");
MAX不是一个很好的名称,因为它更像是一个SUP,或者只是将其重命名为SIZE
在主要情况下,您不使用eventListSize
在AddEventAtIndex中
--i
必须在 i = InputRange(1, 5);
或者只是i = InputRange(1, 5) - 1;
否则,当我的值为5时list[i]
不在列表中,因此您使用未定义的行为写出列表 。
所以最后我没有用的参数,将其删除。
main也不使用return索引,您可以使用它来分配i ,之后不使用i的值。 AddEventAtIndex不需要返回值。
在InputRange中
您无需检查scanf的结果,因此如果输入了无效的整数,并且未清除输入,则所有下一个scanf都无法获得数字,因此timenumber的值是不确定的
同样,如果该值不在范围内,则只需调用InputRange(min, max);
而不返回其值,因此您最终将返回无效值,将所有内容都放入for(;;)
例如,仅在值正确时才返回。
您在InputEvent中使用fgets ,将其与scanf混合以读取数字是问题的根源,请先使用fgets替换scanf ,再在读取行中使用sscanf
在InputEvent中
当你做fgetc(stdin);
您可能希望绕过换行符,但是如果用户在InputRange中的数字之后输入字符(假设输入了数字),则fgets将读取其中的第一个字符,而fgets将无法获得预期的描述。 解决的办法是在InputRange要做然后fgets 的sscanf正如我上面让你删除龟etc说
考虑到我的评论的建议:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
struct event //data type called event which holds time and description for events
{
int hour; //holds the hour digit between 0-23
int minute; //holds the minute digit between 0-59
char description[41]; //holds the description for the reason of the alarm
};
typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"
int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
void AddEventAtIndex(Event list[], Event e);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);
int main (void)
{
Event EventList[MAX];
Event e;
int choice;
/* mark uset entries */
for (int i = 0; i != MAX; ++i)
EventList[i].hour = 24;
do
{
printf("__= Scheduler v1.0 =__\n");
printf("1. Schedule an event.\n");
printf("2. Delete an event.\n");
printf("3. Display schedule.\n");
printf("4. Save schedule.\n");
printf("5. Load schedule.\n");
printf("6. Exit\n");
switch(choice = InputRange(1, 6))
{
case 1:
InputEvent( &e );
AddEventAtIndex(EventList, e);
break;
/*case 2: pHead = deleteStudent(pHead);
break;
case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
scanf("%d", &search);
if (search == 1){
searchStudentID(pHead);
}
else if (search == 2){
searchStudentlName(pHead);
}
else{
printf("Invalid selection");
}
break;
case 4: displayStudentInfo(pHead);
break;
case 5: saveStudentInfo(pHead);
break;
case 6: end(pHead);
break;*/
default: printf("Exiting Program\n\n");
}
}
while ( choice != 6 );
puts("Index #[]\tTime\tDescription");
for ( int j = 0 ; j < MAX ; j++)
{
if (EventList[j].hour != 24)
printf("\t[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
}
int InputRange(int min, int max)
{
char line[32];
int timenumber;
for (;;) {
printf("Please enter a number between %d - %d\n", min, max);
if (fgets(line, sizeof(line), stdin) == NULL)
/* EOF */
exit(-1);
if ((sscanf(line, "%d", &timenumber) == 1) &&
(timenumber >= min) &&
(timenumber <= max))
return timenumber;
printf("Invalid Entry\n");
}
}
Event* InputEvent(Event *newEvent)
{
if (newEvent != NULL) // quality assurance:
// make sure the pointer is valid
{
printf("Enter the event time:\n");
newEvent->hour = InputRange(0, 23);
newEvent->minute = InputRange(0, 59);
printf("Enter the event description:\n");
fgets(newEvent->description, sizeof(newEvent->description), stdin);
printf("\n");
}
return newEvent;
}
void AddEventAtIndex(Event list[], Event e)
{
printf("Where in the array would you like to store this event\n");
int i = InputRange(1, 5) - 1;
list[i].hour = e.hour;
list[i].minute = e.minute;
strcpy(list[i].description, e.description);
}
编译执行:
pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall c.c
pi@raspberrypi:/tmp $ ./a.out
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
2
Please enter a number between 0 - 59
22
Enter the event description:
descr1
Where in the array would you like to store this event
Please enter a number between 1 - 5
1
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
3
Please enter a number between 0 - 59
33
Enter the event description:
descr2
Where in the array would you like to store this event
Please enter a number between 1 - 5
4
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
12
Invalid Entry
Please enter a number between 1 - 6
6
Exiting Program
Index #[] Time Description
[1] 2:22 descr1
[4] 3:33 descr2
请注意最终打印中的空行,这是因为换行符是描述的一部分,因此InputEvent中必须删除它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.