0

我必须为我的 C 编程编写一个程序,将字符串读入 typedef 结构,利用动态数组进行存储,然后计算名称中元音和辅音的数量,元音是 'a'、'e'、'i '、'o'、'u' 和 'y'。字符 – ('-') 既不是辅音也不是元音。然后我需要更新数据,将每个数据添加 3 岁并打印出数据。一切都必须在单独的功能中。

  • 计算所有 7 个名字中元音和辅音的数量
  • 必须使用 typedef 结构和动态分配的数组创建
  • 稍后应通过向每个配置文件添加 3 年来更新功能并打印最终结果

我需要分析的数据是这样的:

Fred Flintstone38男

Barney Rubble36男

威尔玛·弗林特斯通37女

Betty Rubble36女

鹅卵石 Flintstone4Female

Bam-Bam Rubble3Male

迪诺燧石2男

这是我到目前为止所得到的,但程序一直告诉我我有一个不兼容的指针类型,我无法弄清楚错误在哪里。

#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);
4

4 回答 4

3

您在代码中以两种不同的方式使用 pNames。

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

pNames 的类型是为第二次分配适当声明的,但不是为第一次分配。在将第二次分配分配给与第一次分配相同的指针而不释放时,您还泄漏了内存(即第一次分配)。

于 2013-07-29T02:28:24.427 回答
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;
于 2013-07-29T05:43:08.973 回答
0

您将 pNames 声明为 CARTOON* 或指向 CARTOON 的指针,然后存储 char** 或指向 char 指针的指针。那是你的不匹配。

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

换句话说,您已经为 CARTOON 分配了内存,然后将其转换为 char**。

我也注意到了...

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

我不是 100% 确定左侧,但我想在移动和解除指针后,你会得到一个字符。但是,您为该 char(一块 1 字节长的内存)分配了一个指向 char (char*) 的指针,该指针不仅与 char 不兼容,而且取决于您的操作系统,它是 4 到 8 个字节。我觉得这是在自找麻烦,看起来您的循环将覆盖您正在分配的内存。

于 2013-07-29T03:18:41.880 回答
0
CARTOON* pNames;
//later
pNames =(char**)calloc(8,sizeof(CARTOON));

这是不兼容的指针,实际上您不需要强制转换:

pNames = calloc(8,sizeof(CARTOON));
于 2013-07-29T02:26:18.887 回答