C 无效结束问题 [英] C Void ending issue
问题描述
我正在尝试编写一个简单的停车安排代码,我想按 1000 辆车、颜色、车牌和型号对容量进行排序
I am trying to write a simple parking arrangement code, I want to sort the capacity by 1000 vehicles, color, license plate and model
#include <stdio.h>
#include <stdlib.h>
void NewCar()
{
char model[1000][20];
char color [1000][20];
char number[1000][20];
int x = 1;
printf("\nModel: ");
scanf("%s",model[x]);
printf("Color: ");
scanf("%s",color[x]);
printf("Number: ");
scanf("%s",number[x]);
}
void CarList()
{
int x;
char model[1000][20];
char color [1000][20];
char number[1000][20];
for (x ; x >= 1 ; x--)
{
printf("\n%d. Car: %s %s %s",x,number[x],model[x],color[x]);
}
}
int main()
{
char model[1000][20];
char color [1000][20];
char number[1000][20];
char menu;
int x = 1;
flag:
printf("New Car(N)\nCar List(L)\n");
scanf("%s",&menu);
if (menu == "n" || menu == "N")
{
NewCar();
goto flag;
}
if (menu == "l" || menu == "L")
{
CarList();
goto flag;
}
}
当我不使用 void 时,代码可以工作,但我必须使用 void
when i don't use void, the code works but i have to use void
我想要的输出示例;
1. Car Red Jeep FGX9425
2. Car Yellow Truck OKT2637
3. Car Green Sedan ADG4567
....
推荐答案
这是我最喜欢的评论的开头.
This is prefaced by my top comments.
从不使用goto
.使用(例如)一个 while
循环.
Never use goto
. Use (e.g.) a while
loop.
menu
的 scanf
会[可能] 溢出.
Your scanf
for menu
would [probably] overflow.
正如其他人所提到的,一些错误.
As others have mentioned, a number of bugs.
我已经用您的旧代码和一些新代码重构了您的代码.这仍然需要更多的错误检查,并且可以进行更多的概括,但是,我已经测试了它的基本功能:
I've refactored your code with your old code and some new code. This still needs more error checking and can be generalized a bit more, but, I've tested it for basic functionality:
#include <stdio.h>
#include <stdlib.h>
// description of a car
struct car {
char model[20];
char color[20];
char number[20];
};
int
NewCar(struct car *cars,int carcount)
{
struct car *car = &cars[carcount];
printf("\nModel: ");
scanf("%s", car->model);
printf("\nColor: ");
scanf("%s", car->color);
printf("\nNumber: ");
scanf("%s", car->number);
++carcount;
return carcount;
}
void
CarList(struct car *cars,int carcount)
{
struct car *car;
int caridx;
for (caridx = 0; caridx < carcount; ++caridx) {
car = &cars[caridx];
printf("%d. Car: %s %s %s\n",
caridx + 1, car->number, car->model, car->color);
}
}
int
main(int argc,char **argv)
{
#if 1
int carcount = 0;
struct car carlist[1000];
#endif
#if 0
char menu;
int x = 1;
#else
char menu[20];
#endif
// force out prompts
setbuf(stdout,NULL);
while (1) {
printf("New Car(N)\nCar List(L)\n");
#if 0
scanf("%s", &menu);
#else
scanf(" %s", menu);
#endif
// stop program
if ((menu[0] == 'q') || (menu[0] == 'Q'))
break;
switch (menu[0]) {
case 'n':
case 'N':
carcount = NewCar(carlist,carcount);
break;
case 'l':
case 'L':
CarList(carlist,carcount);
break;
}
}
return 0;
}
<小时>
更新:
如你所说,有一些小错误,对我来说不是问题,但是如果你想知道并修复它们,我可以写错误.(如果你写的板之间有空格,代码重复新车列表"命令多次)
As you said, there are a few minor errors, it's not a problem for me, but I can write errors if you want to know and fix them.(if you write the plate with a space between it, the code repeats the "new car car list" command many times)
好的,我制作了一个增强版本,用一个使用 fgets
的函数 askfor
替换了 scanf
.后者将防止 [意外] 缓冲区溢出.而且,混合使用 scanf
和 fgets
可能会有问题.就我个人而言,我总是使用 fgets
来滚动我自己的",因为它可以提供更精细的粒度控制 [如果与包装函数一起使用,例如这里提供的 askfor
]
Okay, I've produced an enhanced version that replaces the scanf
with a function askfor
that uses fgets
. The latter will prevent [accidental] buffer overflow. And, mixing scanf
and fgets
can be problematic. Personally, I always "roll my own" using fgets
as it can provide finer grain control [if used with wrapper functions, such as the askfor
provided here]
Per chux,我已经用使用 strchr
的更安全版本替换了 strlen
以删除换行符:
Per chux, I've replaced the strlen
for removing newline with a safer version that uses strchr
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRMAX 20
// description of a car
struct car {
char model[STRMAX];
char color[STRMAX];
char number[STRMAX];
};
// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{
printf("Enter %s: ",tag);
fflush(stdout);
fgets(ptr,STRMAX,stdin);
// point to last char in buffer
// remove newline
#if 0
ptr += strlen(ptr);
--ptr;
if (*ptr == '\n')
*ptr = 0;
#else
// remove trailing newline [if it exists]
ptr = strchr(ptr,'\n');
if (ptr != NULL)
*ptr = 0;
#endif
}
int
NewCar(struct car *cars,int carcount)
{
struct car *car = &cars[carcount];
askfor("Model",car->model);
askfor("Color",car->color);
askfor("Number",car->number);
++carcount;
return carcount;
}
void
CarList(struct car *cars,int carcount)
{
struct car *car;
int caridx;
for (caridx = 0; caridx < carcount; ++caridx) {
car = &cars[caridx];
printf("%d. Car: %s %s %s\n",
caridx + 1, car->number, car->model, car->color);
}
}
int
main(int argc,char **argv)
{
int carcount = 0;
struct car carlist[1000];
char menu[STRMAX];
// force out prompts
setbuf(stdout,NULL);
while (1) {
askfor("\nNew Car(N)\nCar List(L)",menu);
// stop program
if ((menu[0] == 'q') || (menu[0] == 'Q'))
break;
switch (menu[0]) {
case 'n':
case 'N':
carcount = NewCar(carlist,carcount);
break;
case 'l':
case 'L':
CarList(carlist,carcount);
break;
}
}
return 0;
}
<小时>
更新 #2:
感谢您修复错误,但正如我在问题中所说,我必须使用 void 来实现新车"功能.你用 int
做的,你能用 void
做吗?
Thank you for your bug fix, but as I said in my question, I have to do the "New car" feature using void. You did it with
int
, can you do it withvoid
?
好的.当您说使用 void"时,我 [或其他一些人] 并不完全清楚您的意思.存在足够多的错误,它们掩盖了其他一些考虑因素.
Okay. When you said "using void", what you meant wasn't totally clear to me [or some others]. There were enough bugs that they overshadowed some other considerations.
所以,我必须假设使用 void"意味着函数返回 void
.
So, I have to assume that "using void" means that the functions return void
.
您的原始函数定义为 void NewCar()
和 void CarList()
.那些无法按原样完成工作,因此必须对其进行更改.
Your original functions were defined as void NewCar()
and void CarList()
. Those could not have done the job as is, so they had to be changed.
如果你有类似的标准,更好的表达方式是:
If you have similar criteria, a better way to phrase that would be:
我必须创建两个函数,具有以下函数签名...
I must create two functions, with the following function signatures ...
无论如何,这是更新后的代码:
Anyway, here's the updated code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRMAX 20
// description of a car
struct car {
char model[STRMAX];
char color[STRMAX];
char number[STRMAX];
};
// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{
printf("Enter %s: ",tag);
fflush(stdout);
fgets(ptr,STRMAX,stdin);
// remove trailing newline [if it exists]
ptr = strchr(ptr,'\n');
if (ptr != NULL)
*ptr = 0;
}
void
NewCar(struct car *cars,int *countptr)
{
int carcount = *countptr;
struct car *car = &cars[carcount];
askfor("Model",car->model);
askfor("Color",car->color);
askfor("Number",car->number);
carcount += 1;
*countptr = carcount;
}
void
CarList(struct car *cars,int carcount)
{
struct car *car;
int caridx;
for (caridx = 0; caridx < carcount; ++caridx) {
car = &cars[caridx];
printf("%d. Car: %s %s %s\n",
caridx + 1, car->number, car->model, car->color);
}
}
int
main(int argc,char **argv)
{
int carcount = 0;
struct car carlist[1000];
char menu[STRMAX];
// force out prompts
setbuf(stdout,NULL);
while (1) {
askfor("\nNew Car(N)\nCar List(L)",menu);
// stop program
if ((menu[0] == 'q') || (menu[0] == 'Q'))
break;
switch (menu[0]) {
case 'n':
case 'N':
#if 0
carcount = NewCar(carlist,carcount);
#else
NewCar(carlist,&carcount);
#endif
break;
case 'l':
case 'L':
CarList(carlist,carcount);
break;
}
}
return 0;
}
但是,鉴于您的原始函数,签名必须可能是:void NewCar(void)
和 void CarList(void)
并且汽车列表变量必须是全局范围.
However, given your original functions, it may be possible that the signatures have to be: void NewCar(void)
and void CarList(void)
and that the car list variables must be global scope.
这将是一种不太灵活和理想的做事方式,但这里有一个仅使用列表全局变量的版本:
This would be a less flexible and desirable way to do things, but here is a version that uses only global variables for the lists:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRMAX 20
// description of a car
struct car {
char model[STRMAX];
char color[STRMAX];
char number[STRMAX];
};
#if 1
int carcount = 0;
struct car carlist[1000];
#endif
// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{
printf("Enter %s: ",tag);
fflush(stdout);
fgets(ptr,STRMAX,stdin);
// remove trailing newline [if it exists]
ptr = strchr(ptr,'\n');
if (ptr != NULL)
*ptr = 0;
}
void
NewCar(void)
{
struct car *car = &carlist[carcount];
askfor("Model",car->model);
askfor("Color",car->color);
askfor("Number",car->number);
carcount += 1;
}
void
CarList(void)
{
struct car *car;
int caridx;
for (caridx = 0; caridx < carcount; ++caridx) {
car = &carlist[caridx];
printf("%d. Car: %s %s %s\n",
caridx + 1, car->number, car->model, car->color);
}
}
int
main(int argc,char **argv)
{
#if 0
int carcount = 0;
struct car carlist[1000];
#endif
char menu[STRMAX];
// force out prompts
setbuf(stdout,NULL);
while (1) {
askfor("\nNew Car(N)\nCar List(L)",menu);
// stop program
if ((menu[0] == 'q') || (menu[0] == 'Q'))
break;
switch (menu[0]) {
case 'n':
case 'N':
#if 0
carcount = NewCar(carlist,carcount);
#else
NewCar();
#endif
break;
case 'l':
case 'L':
#if 0
CarList(carlist,carcount);
#else
CarList();
#endif
break;
}
}
return 0;
}
这篇关于C 无效结束问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!