2013-07-29 23 views
0

我必須爲我的C編程編寫一個程序,它將字符串讀入一個typedef結構,利用它的動態數組存儲,然後計算名稱中元音和輔音的數量,元音是'a','e', '我','O','你'和'Y'。字符 - (' - ')既不是輔音也不是元音。然後我需要更新每個年齡增加3歲的數據並打印出數據。一切都必須在不同的功能。爲什麼我在C中有一個不兼容的指針類型?

  • 計算在所有7名
  • 必須使用的typedef結構和動態分配的陣列創建元音和輔音的量
  • 功能稍後應通過加入3年每個簡檔被更新,並印有最終結果

,我需要分析的數據是這樣的:

弗雷德Flintstone38Male

巴尼Rubble36Male

威爾瑪Flintstone37Female

貝蒂Rubble36Female

卵石Flintstone4Female

巴姆 - 巴姆Rubble3Male

迪諾Flintstone2Male

這是我這麼遠,但程序不斷告訴我我有一個不兼容的指針類型,我無法弄清楚錯誤在哪裏。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 


typedef struct 
    { 
     char name[20]; 
     int age[2]; 
     char gender[6]; 
    }CARTOON; 

// Function Prototype Declarations 
int printit(CARTOON *, FILE *); 
int loaddata(CARTOON *, int, FILE *, FILE *); 
void countVowel (char **pNames, int *vowel, int *consonants); 
void printResults (int vowel, int consonants); 

// Main 
int main (void) 
{ 
    char input[40]; 

    int namesIndex; 
    int vowel; 
    int consonants; 

    CARTOON* pNames; 
    FILE *tptr; 
    FILE *bptr; 


    FILE *fptr; //reading in the file "data.txt" 
    if ((fptr=fopen("data.txt", "r"))==NULL) 
    { 
     printf("Error opening data.txt\n"); 
     return -1; 
    } 

    if((bptr=fopen("lab5dat.bin","wb"))==NULL) 
    { 
     printf("Error creating lab4.bin\n"); 
     return 2; 
    } 

    pNames =(char**)calloc(8,sizeof(CARTOON)); 
    namesIndex = 0; 
    while (namesIndex < 8 && fgets(input,40,fptr)) 
    { 
     *(pNames + namesIndex)=(char*) calloc(strlen(input)+1, sizeof(char));//pointer to first string in array namesIndex 
     strcpy(*(pNames + namesIndex), input); 
     namesIndex++; 
    } 
    *(pNames + namesIndex)=NULL; 
    namesIndex = 0; 
    pNames=(CARTOON*) calloc(12,sizeof(CARTOON)); 
    loaddata(pNames, namesIndex, tptr, bptr); 
    fclose(tptr); 
    fclose(bptr); 
    if((bptr=fopen("lab5dat.bin","rb"))==NULL) 
    { 
     printf("Error opening lab5dat.bin\n"); 
     return 3; 
    } 
    //printit(pNames, bptr); 



// Prints the items in the "lab3.dat" file. 
    namesIndex=0; 
    while (*(pNames + namesIndex)) 
    { 
     printf("%s\n", *(pNames + namesIndex)); 
     namesIndex++; 
    } 

// Calls function countVowel 
    countVowel (pNames, &vowel, &consonants); 

//Calls function printResults 
    printResults(vowel, consonants); 

    system("pause"); 
    return 0; 
} //end 


int printit(CARTOON *pNames, FILE *bptr) 
{ 
    int num; 
    printf("Data from print \n\n"); 
    //num=fread(pNames, sizeof(CARTOON), 1, bptr); 
    while (!(feof(bptr))) 
    { 
     num=fread(pNames, sizeof(CARTOON), 1, bptr); 
     printf("%s %d %s \n",pNames->name,pNames->age,pNames->gender); 
    } 
    return 0; 
} 

int loaddata(CARTOON *pNames, int namesIndex, FILE *tptr, FILE *bptr) 
{ 
    printf("Data from loaddata\n\n"); 
    while (!(feof(tptr))) 
    { 
     fgets((pNames + namesIndex)->name,20,tptr); 
     fscanf(tptr,"%d",&pNames[namesIndex].age); 
     fgets((pNames + namesIndex)->gender,18,tptr); 
     fwrite((pNames + namesIndex),sizeof(CARTOON),1,bptr); 
     printf("%s\n", (pNames + namesIndex)->name); 
     namesIndex++; 
    } 
    return 0; 
} 


//function countVowel will count the number of vowels and consonants 
void countVowel (char **pNames, int *vowel, int *consonants) 
{ 
    int namesIndex; 
    int stringIndex; 

    namesIndex=0; 
    stringIndex=0; 
    *vowel=0; 
    *consonants=0; 

    while(*(pNames + namesIndex)) 
    { 
     stringIndex=0; 
     while(stringIndex<strlen(*(pNames + namesIndex))) 
     { 
      if (isalpha (pNames[namesIndex][stringIndex])) //Reads only alphabets 
       switch (toupper(pNames[namesIndex][stringIndex])) //makes everything capitalized. 
      { case 'A': (*vowel)++ ;break; //*vowel count gets incremented by 1 whenever a vowel is found. 
       case 'E': (*vowel)++ ;break; 
       case 'I': (*vowel)++ ;break; 
       case 'O': (*vowel)++ ;break; 
       case 'U': (*vowel)++ ;break; 
       case 'Y': (*vowel)++ ;break; 
       default: (*consonants)++;break; // Everything that is not a vowel increments consonants by 1. 
      } 

      stringIndex++; // goes to the next index in the string 
     } 

     namesIndex++; //goes to the next array index, when end of string is reached 
    } 

} 

//Prints the result of the number of vowels and consonants 
void printResults (int vowel, int consonants) 
{ 
    printf ("\n\nThere are %d vowels and %d consonants\n\n", vowel, consonants); 
} 

眼下錯誤代碼的這兩條線之間

*(pNames + namesIndex)=(char*) calloc(strlen(input)+1, sizeof(char));//pointer to first string in array namesIndex 
strcpy(*(pNames + namesIndex), input); 
+2

嗯,人們通常不想通讀大量的代碼。告訴我們哪行代碼出錯會有幫助,不是嗎? – OldProgrammer

+4

「程序不斷告訴我,我有一個不兼容的指針類型」 - 當然它也說*哪裏*? – usr2564301

+1

不要強制轉換malloc,calloc或realloc的返回值。我不在乎你是否想要使用C++編譯器。這是C,而不是C++,而在C中,投入malloc,calloc或realloc是愚蠢的。 – Sebivor

回答

3

您在代碼中以兩種不同的感官使用pName。

CARTOON* pNames; 
... 
pNames =(char**)calloc(8,sizeof(CARTOON)); 
... 
pNames=(CARTOON*) calloc(12,sizeof(CARTOON)); 

pName的類型爲第二次分配適當聲明,但不適用於第一次。在將第二次分配分配給與第一次分配相同的指針而不釋放時,您也泄漏了內存(即第一次分配)。

+0

謝謝,但我仍然收到有關使用不兼容類型的第52行和第52行的警告。我如何解決這個問題? –

+1

@DenysKorovets通過不使用不兼容的類型。 –

0
CARTOON* pNames; 
//later 
pNames =(char**)calloc(8,sizeof(CARTOON)); 

這裏是不兼容的指針,你並不需要真正投:

pNames = calloc(8,sizeof(CARTOON)); 
+0

仍然沒有幫助... –

+1

我只是顯示一個,閱讀錯誤信息,我確定它有不兼容指針的位置信息。 –

0

您將pName聲明爲CARTOON *,或指向CARTOON的指針,然後存儲char **或指向char的指針。那是你的錯配。

pNames =(char**)calloc(8,sizeof(CARTOON)); 

換句話說,你已經爲CARTOON分配了內存,然後將它轉換爲char **。

我也注意到...

*(pNames + namesIndex)=(char*) calloc(strlen(input)+1, sizeof(char)); 

我不是100%地肯定左側,但我想像移位和derefing指針後,你有一個char結束了。然而,你將char(一個1字節長的內存)分配給一個指向char(char *)的指針,該指針不僅與char不兼容,而且取決於您的操作系統是4到8個字節。我覺得這是在尋求麻煩,看起來你的循環將會覆蓋你正在分配的內存。

0

你的代碼有很多複雜性。您正試圖將完整的輸入字符串存儲到結構中。它不會在結構元素內正確分配數據。

對於前:

你直接複製結構內部的輸入。我不認爲它會按預期工作。

strcpy(*(pNames + namesIndex), input); 

我建議你解析輸入和單獨名稱,年齡和性別,然後將它存儲在你的結構中。它將允許您在後期很容易地從結構中訪問數據。

temp_name="Fred Flintstone"; 
temp_age=38; 
temp_gender="Male"; 

解析後,將其存儲到結構中。

pNames[0].name=temp_name; 
pNames[0].age=temp_age; 
pNames[0].gender="Male"; 

在解析輸入到單獨的三個字段,你可以做上面的改造,就可以計算出元音,增加的年齡。(在一個方法中的所有動作)。 否則你可以創建三個模塊來做所有事情。

Module 1: parse data and store it into structure. 
Module 2: find Vowels pasing the structure into it. 
Module 3: increment age passing structure into it. 

另外,輸入姓名,性別在本質上是動態的。它可以容納任意數量的字符。我會要求你儘可能動態地使用你的結構。當前結構只能保存20個字符的名稱。

typedef struct 
{ 
    char name[20]; // Allows maximun of 20 characters. 
    int age[2]; // Holds two age for a person which is not a practical scenario. 
    char gender[6]; //Holds maximum of 6 characters. 
}CARTOON; 

這不符合您的要求。你已經使用數組來存儲年齡,但你直接調用年齡是不可能的。

printf("%s %d %s \n",pNames->name,pNames->age,pNames->gender); //pNames->age[0] or pNames->age[1] 
fscanf(tptr,"%d",&pNames[namesIndex].age); // &pNames[namesIndex].age[0] or &pNames[namesIndex].age[1] 

您可以改爲嘗試下列結構。

typedef struct 
{ 
    char *name; 
    int age; 
    char *gender; 
}CARTOON;