我必须为我的C编程编写一个程序,它将字符串读入一个typedef结构,利用动态数组存储它,然后计算名称中的元音和辅音数量,元音是'a','e' ,'我','o','你'和'y'。字符 - (' - ')既不是辅音也不是元音。然后我需要更新每个添加3年的数据并打印出数据。一切都必须在不同的功能中。
我需要分析的数据是:
Fred Flintstone38Male
Barney Rubble36Male
Wilma Flintstone37女性
Betty Rubble36Female
Pebbles Flintstone4Female
Bam-Bam Rubble3Male
Dino 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);
答案 0 :(得分:3)
您在代码中使用了两种不同的pName。
CARTOON* pNames;
...
pNames =(char**)calloc(8,sizeof(CARTOON));
...
pNames=(CARTOON*) calloc(12,sizeof(CARTOON));
pNames的类型适用于第二次分配,但不适用于第一次分配。在将第二个分配分配给与第一个没有释放的第一个指针时,你也泄漏了内存(即第一次分配)。
答案 1 :(得分:0)
CARTOON* pNames;
//later
pNames =(char**)calloc(8,sizeof(CARTOON));
这是不兼容的指针,你实际上不需要强制转换:
pNames = calloc(8,sizeof(CARTOON));
答案 2 :(得分:0)
您将pNames声明为CARTOON *,或指向CARTOON的指针,然后存储char **或指向char的指针。那是你的不匹配。
pNames =(char**)calloc(8,sizeof(CARTOON));
换句话说,你为CARTOON分配了内存,然后将其转换为char **。
我也注意到了......
*(pNames + namesIndex)=(char*) calloc(strlen(input)+1, sizeof(char));
我对左侧并不是百分之百确定,但是我想在移动和解散指针之后,你最终会得到一个字符。但是,您正在为char(一个1字节长的内存)分配一个指向char(char *)的指针,该指针不仅与char不兼容,而且取决于您的操作系统,为4到8个字节。我觉得这是在寻找麻烦,看起来你的循环会覆盖你正在分配的内存。
答案 3 :(得分: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;