此代码用于输入一个输入文本文件" playlist.txt",它由一些歌曲名称组成,每个歌曲名称各自独立。然后它将播放列表混洗7次,并将洗牌后的列表输出到名为" shuffle [星期几]"的文件中。
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
void open(char *playlist, int *size);
void shuffle(char *playlist, int size, char *day);
int main()
{
char playlist[5000];
int size = 0;
open(playlist, &size);
time_t t;
srand((unsigned) time(&t));
shuffle(playlist, size, "Monday");
shuffle(playlist, size, "Tuesday");
shuffle(playlist, size, "Wednesday");
shuffle(playlist, size, "Thursday");
shuffle(playlist, size, "Friday");
shuffle(playlist, size, "Saturday");
shuffle(playlist, size, "Sunday");
}
void open(char *playlist, int *size)
{
FILE *in = fopen("playlist.txt", "r");
int i = 0;
while(fgets(&playlist[i], 30, in) != NULL)
{
i++;
(*size)++;
}
fclose(in);
}
void shuffle(char *playlist, int size, char *day)
{
printf("started %s shuffle\n", day);
int done = 0;
int n, i, j;
int tempsize = size;
char templist[5000];
for(i = 0; i < size; i++)
{
strcpy(&templist[i], &playlist[i]);
}
char newlist [5000];
for(i = 0; i < size; i++)
{
n = rand()%tempsize;
strcpy(&newlist[i], &templist[n]);
for(j = n; j < tempsize; j++)
{
strcpy(&templist[j], &templist[j+1]);
}
tempsize--;
}
char listname[20] = "shuffle";
strcat(listname, day);
strcat(listname, ".txt");
FILE *out = fopen(listname, "w");
for(i = 0; i < size; i++)
{
fprintf(out, "%s\n", &newlist[i]);
}
fclose(out);
printf("Finished %s shuffle\n", day);
}
当我运行它时,输出表示周一和周二都开始并完成。然后说星期三开始了,但后来我得到了Abort陷阱6。 只创建了星期一和星期二的输出文件,但它们都包含看似随机的字符,它们之间有随机数字的换行符。
我做错了什么? 如何修复中止陷阱?
答案 0 :(得分:0)
除了user3629249识别的错误(由于星期三因文件名中的一个字节溢出)之外,您用于播放列表和临时列表的数据类型也不正确。如果你想要一个5000首歌曲的播放列表,每个歌曲由一串文字标识,你需要
char *playlist[5000]; /* an 5000-element array of char *s. */
char *templist[5000]; /* ditto */
如你所知,&amp; playlist [i]是5000个元素字符数组的第i个字符,而不是5000个元素char * s的第i个字符串指针。在当前的实现中,您在迭代时逐字节地继续踩数据。如果更改为char *数组,则将按指针步进指针。
但是!请注意,您声明了一个固定大小的数组(5000个元素),但您无法确认您是否尝试编写超过5000个元素,这也可能导致Abort(信号6)或Segfault(信号9)。