我没有编译错误,但它在运行时崩溃, 这是我的相关代码,首先是它的结构:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Gas_Station *pgasStationHead = NULL;
typedef struct Gas_Station {
char *name;
double octan95SS;
double octan95FS;
double octan98SS;
double octan98FS;
double gasSoldTotal;
double gasSoldSS;
double gasSoldFS;
struct Gas_Station *pgasStationNext;
struct Client_List *pclientHead;
} Station;
typedef struct Client_List {
char carID[10];
char gasType[3];
double gasAmount;
char serviceType[12];
struct Client_List *pclientNext;
} Client;
之后是有问题的区域:
void CommandsSwitch(FILE *input , FILE *output) {
do {
int i;
char *ptemp , *pfuncNum, *pcarID, *pstationName;
ptemp = fgets(ptemp , 80 , input);
if (ptemp[0] != '#') {
pfuncNum = strtok(ptemp , ",");
i = (int)pfuncNum[0];
switch (i)
{
case 1:
HowMuchGasPerStation(output);
break;
case 2 :
pstationName = strtok(pstationName , ",");
AverageGasInSpecieficStation(output , pstationName);
break;
case 3 :
HowMuchGasInAllStations(output);
break;
case 4 :
HowMuchGasFSInAllStations(output);
break;
case 5 :
pcarID = strtok(ptemp , ",");
HowMuchGasSoldByCarID(output , pcarID);
break;
case 6 :
pcarID = strtok(ptemp , ",");
pstationName = strtok(pstationName , ",");
HowMuchGasSoldByStationPerCarID(output , pcarID , pstationName);
break;
case 7 :
pcarID = strtok(ptemp , ",");
StationsWithClientByCarID(output , pcarID);
break;
case 8 :
pcarID = strtok(ptemp , ",");
pstationName = strtok(pstationName , ",");
HowMuchClientSpentByStation(output , pcarID , pstationName);
break;
case 9 :
pcarID = strtok(ptemp , ",");
HowMuchClientSpentInTotalByCarID(output , pcarID);
break;
case 10 :
pstationName = strtok(pstationName , ",");
ClientDetailsBySpecieficStation(output , pstationName);
break;
}
}
}while(!feof(input));
fclose(input);
fclose(output);
}
int main (int argc, char* argv[]) {
int i;
FILE *f , *input , *output;
for (i = 2; i < argc; i++) {
f = fopen(argv[i] , "r");
if (f == NULL) {
error("can't open file, might not exists");
}
else {
AddStation(f);
fclose(f);
}
}
if (argv[1] != NULL) {
input = fopen(argv[1] , "r");
if (input == NULL) {
error("can't open file, might not exists");
}
}
output = fopen("result.txt" , "w");
if (output == NULL) {
error("can't open file");
}
CommandsSwitch(input , output);
return 0;
}`
在CommandSwitch函数中,Call堆栈指向* ptemp,说我不能使用它,因为它没有初始化或者什么...... 我做错了什么?!
答案 0 :(得分:7)
您的ptemp
变量是未初始化的指针。
使用malloc
来分配适当的空间或将其定义为数组。
答案 1 :(得分:4)
在使用ptemp
之前,您必须为fgets
分配内存。
您可以动态地或在堆栈上执行此操作:
char ptemp[100];
char* ptemp = (char*)malloc(100);
答案 2 :(得分:2)
这是一个问题。
char *ptemp;
ptemp = fgets(ptemp , 80 , input);
您告诉编译器ptemp
是指向某些字符的指针,但您从未分配空间来存储要写入的某些字符。也许这应该是:
char ptemp[80];
fgets(ptemp, sizeof(ptemp), input);
答案 3 :(得分:0)
在fgets()之前执行char ptemp[80];
可以帮助解决错误。或者在fgets()之前ptemp = (char *)malloc(80*sizeof(*ptemp));
。
答案 4 :(得分:0)
完成处理ptemp
作为未初始化指针后,您可能也想要更改此部分:
pfuncNum = strtok(ptemp , ",");
i = (int)pfuncNum[0];
switch (i)
{
case 1:
// more cases up to `10` elided.
现在,您正在查看第一个字符的字符值,因此要获得1
,用户必须输入Ctrl + A,2
Ctrl + B,并且等等。获得10
会特别成问题,因为那是一个line-feed
字符。
我的猜测是你想要的东西:
i = atoi(pfuncNum);
switch (i) {
// ...
这将让用户在命令中实际输入数字1
,2
等。
对于实际使用,您可能希望将atoi
替换为类似strtol
的内容(它可以提高处理错误输入的能力等等)。
一旦你修复了它,你还想再看一下你的循环的基本结构。几乎所有形式的循环:
do {
/* ... */
} while (!feof(input));
...几乎可以保证它无法正常工作(通常会处理最后一次输入两次)。由于您使用fgets
来读取字符串,因此您可能希望使用类似的内容:
while (fgets(...)) {
/* ... */
};