1

问题说有两个结构

第一个结构应该有这些成员(称为标题的字符串,长度为 15 个字符,称为长度的双精度数,类型为枚举类型的流派,其中一种流派作为枚举常量 Blues、HipHop、Jazz、Country、Electronic、Rock、Other)。

第二个结构应该有(称为标题的字符串,长度为 20 个字符,字符串称为艺术家,长度为 30 个字符,成员称为歌曲类型的歌曲,其中包含最多 4 首歌曲,最后一个成员称为整数 var,用作歌曲数计数器。)

struct song 必须别名为 Song。
struct album 必须别名为 Album。

我的程序是这样的

enum genres { Blues = 0, HipHop, Jazz, Country, Electronic, Rock, Other};

struct song {
  char title[15];
  double length;
  enum genres genre;
};

typedef struct song Song;
struct album { 
char title[20];
char artist[30];
Song songs[4];
int noOfSongs;
};
typedef struct album Album;

现在从这里我遇到了问题,因为问题说。有:

  1. getAlbum函数,将专辑指针作为参数,提示用户输入专辑标题和艺术家姓名。
  2. getSong以专辑指针为参数的函数,提示用户输入歌曲名称和歌曲长度以及该歌曲的流派。
  3. printAlbum功能 该功能显示用户提示的信息。

请注意,专辑中的歌曲数量最多为 4 首。

我想出了这些函数原型

void getAlbum( Album *aPtr);
void getSong( Album *sPtr);
void printAlbum( Album *pPtr);

我在功能和实现方面遇到问题,而且我不确定我的枚举和结构专辑是否正确,因为我无法访问它们。

4

2 回答 2

0

由于编译器总是将类型填充为 4 字节的倍数(char = 1 字节),因此您的缓冲区可以使用该空间而无需任何额外费用。'\0'无论如何,您都需要它作为终止角色。顺便说一句,缩短定义怎么样?

typedef enum { Blues, HipHop, Jazz, Country, Electronic, Rock, Other} Genre;

typedef struct {
  char title[16];
  double length;
  Genre genre;
}
Song;

typedef struct { 
  char title[21];
  char artist[31];
  Song songs[4];
  int noOfSongs;
}
Album;

typedef struct album { ... } Album;如果你也需要这个名字,你当然可以写struct album,但在你的情况下,我看不出有任何理由。以下是功能:

void getAlbum(Album *aPtr) {
  printf("Album: ");
  scanf("%20s", aPtr->title);
  printf("Artist: ");
  scanf("%30s", aPtr->artist);
  int no = -1;
  while(no < 0 || no > 4) {
    printf("Tracks: ");
    scanf("%d", no);
  }
  aPtr->noOfSongs = no;
  for(int i = 0; i < no; ++i) getSong(&aPtr->songs + i);
}

void getSong(Song *sPtr) {
  printf("Song: ");
  scanf("%15s", sPtr->title);
  double len = -1;
  while(len < 0 || len > 100) {
    printf("Length: ");
    scanf("%f", len);
  }
  char genre[16];
  int genreNo = -1;
  while(genreNo == -1) {
    printf("Genre: ");
    scanf("%15s", genre);
    if(strcmp(genre, "Blues") == 0) genreNo = 0;
    else if(strcmp(genre, "Hip Hop") == 0) genreNo = 1;
    ...
    else genreNo = 6;
  }
  sPtr->genre = (Genre)genreNo;
}

void printAlbum(Album *aPtr) {
  printf("Album: %s\nArtist: %s\n", aPtr->title, aPtr->artist);
  for(int i = 0; i < aPtr->noOfSongs; ++i) printSong(&aPtr->songs + i);
}

void printSong(Song *sPtr) {
  printf("\tSong: %s\n\tLength: %.2f\n\tGenre: ", sPtr->title, sPtr->length);
  switch(sPtr->genre) {
    case Blues: printf("Blues\n"); break;
    case HipHop: printf("Hip Hop\n"); break;
    ...
    default:  printf("Other\n"); break;
  }
}
于 2013-05-05T20:48:15.513 回答
0

实现一个函数实际上相当简单。您已经获得了原型,因此您只需添加括号即可获得基本功能:

void getAlbum(Album *aPtr) {

}

当然,这还不会做任何事情,所以让我们从一个简单的提示开始:

void getAlbum(Album *aPtr) {
    printf("Enter the album name: ");
}

这现在将显示文本,但不会询问实际文本。为此,还有几种不同的方法。我将在scanf()这里使用它,尽管它只应用于测试目的和(可能)内部工具,因为它可能相当棘手且容易出错(例如,如果输入了垃圾)。

void getAlbum(Album *aPtr) {
    printf("Enter the album name: ");
    scanf("%19s", aPtr->title); // read up to 19 characters as a (s)tring; the 20th will be the terminator ('\0')
}

你去吧。只需扩展它以读取所需的所有值。功能相同getSong()

打印所有内容将非常相似,只需将成员作为参数传递 aprintf()而不是scanf().

于 2013-05-05T20:48:47.020 回答