C指针,我做错了什么?

时间:2010-11-15 21:38:34

标签: c pointers runtime-error

我没有编译错误,但它在运行时崩溃, 这是我的相关代码,首先是它的结构:

#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,说我不能使用它,因为它没有初始化或者什么...... 我做错了什么?!

5 个答案:

答案 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) { 
// ...

这将让用户在命令中实际输入数字12等。 对于实际使用,您可能希望将atoi替换为类似strtol的内容(它可以提高处理错误输入的能力等等)。

一旦你修复了它,你还想再看一下你的循环的基本结构。几乎所有形式的循环:

do { 
    /* ... */ 
} while (!feof(input));

...几乎可以保证它无法正常工作(通常会处理最后一次输入两次)。由于您使用fgets来读取字符串,因此您可能希望使用类似的内容:

while (fgets(...)) {
    /* ... */ 
};