我正在为大学作业创建一个程序,用户需要输入艺术家和他们的歌曲。程序然后按字母顺序对它们进行排序并将它们混洗。艺术家名称存储在名为artists[][80]
的数组中,歌曲名称存储在songsArtistx
中,其中x是1到4之间的数字。我初始化所有数组以填充NULL终结符 - '\ 0 ”。要使程序正常工作,我需要找到输入的歌曲数量(必须至少为1,但可以是3或更少)。为此,我使用了一个名为checkSongs
的函数:
int checkSongs(char songsOfAnArtist[][80])
{
int i,numOfSongs;
//Loop goes through 4 possible artists.
for (i=0;i<4;i++)
{
//Assume there are 3 songs for each artits, and decrement by 1 each time an empty string occurs.
numOfSongs = 3;
if (songsOfAnArtist[i][0]=='\0' || songsOfAnArtist [i][0] == '\n')
{
numOfSongs--;
break;
}
}
return numOfSongs;
}
然而,当歌曲的数量小于3时,这个函数给我一个错误的结果。这是命令行的一个例子,还有来自调试器的变量的屏幕截图:
在上面的照片中,最后一行的数字表示输入的艺术家数量(在这种情况下是正确的)和songsArtsist1
,songsArtsist2
,{{1}中的歌曲数量},songsArtsist3
。最后一个数字是艺术家的数量。
如何更改我的代码,以便songsArtsist4
返回为每位艺术家输入的歌曲数量?
以下也是主文件的摘录,可能与问题有关:
checkSongs
这里有数组:
//Get all inputs from command line: artists and songs
getInputs(artists,songsArtist1,songsArtist2,songsArtist3,songsArtist4);
//Use checkArtists to store the number of entered artists in variable 'numOfArtists'
numOfArtists = checkArtists(artists);
printf("%d ",numOfArtists);
//Use check songs to store number of songs per artist in array 'numSongsPerArtists'
numSongsPerArtist[0] = checkSongs(songsArtist1);
numSongsPerArtist[1] = checkSongs(songsArtist2);
numSongsPerArtist[2] = checkSongs(songsArtist3);
numSongsPerArtist[3] = checkSongs(songsArtist4);
//DEBUG
printf("%d ",numSongsPerArtist[0]);
printf("%d ",numSongsPerArtist[1]);
printf("%d ",numSongsPerArtist[2]);
printf("%d ",numSongsPerArtist[3]);
printf("%d ",numOfArtists);
答案 0 :(得分:1)
当你编写一个以数组作为参数的函数时,它总是应该问
来自调用者的长度,除非以某种方式标记数组的末尾
(如字符串'\0
')。如果您以后更改程序以接受更多或
歌曲数量减少,你忘记更新循环条件,你在一个
麻烦的世界。调用者知道数组的大小,因为它
创建了数组,或者因为数组及其大小已经传递。这是
标准C库中函数的标准行为。
所以我将你的功能重写为:
int checkSongs(char songsOfAnArtist[][80], size_t len)
{
int numOfSongs = 0;
for(size_t i = 0; i < len; ++i)
{
if(songsOfAnArtist[i][0] != 0 && songsOfAnArtist[i][0] != '\n')
numOfSongs++;
}
return numOfSongs;
}
然后调用函数
numSongsPerArtist[0] = checkSongs(songsArtist1, sizeof songsArtist1 / sizeof *songsArtist1);
numSongsPerArtist[1] = checkSongs(songsArtist2, sizeof songsArtist2 / sizeof *songsArtist2);
numSongsPerArtist[2] = checkSongs(songsArtist3, sizeof songsArtist3 / sizeof *songsArtist3);
numSongsPerArtist[3] = checkSongs(songsArtist4, sizeof songsArtist4 / sizeof *songsArtist4);
这样更好,因为如果您稍后从char songsArtist3[3][80];
更改为
char songsArtist3[5][80];
,你不必重写边界
循环条件。每个艺术家都可以拥有不同大小的歌曲插槽。
当您存储歌曲名称时,请确保源字符串不是
如果长度超过79个字符,请使用strncpy
,并确保编写'\0'
- 终止字节。
如果你得到错误的结果,则可能是songsArtist
s
变量未正确初始化,请检查您的getInputs
函数
这样在初始化时所有 songsArtist[i][0]
都设置为0。如果你这样做
那,你应该得到正确的结果。
例如:
int main(void)
{
...
char songsArtist1[3][80];
char songsArtist2[3][80];
char songsArtist3[3][80];
char songsArtist4[3][80];
memset(songsArtist1, 0, sizeof songsArtist1);
memset(songsArtist2, 0, sizeof songsArtist2);
memset(songsArtist3, 0, sizeof songsArtist3);
memset(songsArtist4, 0, sizeof songsArtist4);
...
}
答案 1 :(得分:0)
在您打破循环的区块中添加条件。
if(sumOfSongs==0)
break;
此外,我建议使用unsigned
类型作为变量,因为数字最有可能永远不会小于0;
并将numOfSongs = 3;
置于for
循环之外,正如其他人所建议的那样。