- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难找到大学作业中的问题。该程序是一个音乐播放器,它有大约 5 个功能,都可以正常工作,但只有一个功能是将歌曲添加到播放列表中。问题出在函数的第二次调用上,此时它必须将第二首歌曲添加到字符串数组 playList 中。我注意到调试代码时,当我在 fgets() 函数之后按 Enter 时,它会将 playList[0] 更改为我刚刚编写的内容,甚至没有输入修改数组的函数。所以我认为问题来自于函数之外的其他地方。我会使用动态数组,这会好得多,但我不允许使用动态内存 D:(抱歉,如果我拼写错误,英语不是我的主要语言)。我相信问题出在函数 fill_playlist 中,也许当我将字符串分配给 playList[i] 但我找不到位置时。当我在另一个菜单选项“搜索记录”中调用 fgets 时也会发生这种情况。我认为这是我缺少的指针算术问题。基本上每次我使用 fgets() 时,playList[0] 都会立即填充最后写入的字符串,而我无法填充 playList[1] 或更多。
谢谢
http://pastebin.com/FX2bHUSk
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#define LIBRARY_DIRECTORY "/home/user/Desktop/library/"
#define MSG_RANDOM_LIST "How many songs would you like to randomly listen?"
#define MSG_RANDOM_ERR "There are not that many songs in the list!"
#define MSG_INPUT_ERROR "There has been an input error!"
#define MSG_SEARCH "These are the songs in the playlist that contain the keyword: "
#define MSG_EMPTY_LIST "The list is empty! You can add records using the 'Add Record' function."
#define MSG_FULL_LIST "The list is full, you have added all the songs in the library!"
#define MSG_ALREADY_IN "The song you intend to add is already on the playlist. Please try with another one."
#define MSG_ADD_RECORD "Write the name of the song you would like to add."
#define MSG_WRONG_NAME "The song you entered is not in the list, please add another one."
#define MSG_SUCCESFUL_ADD "The song you wrote was succesfully added to the playlist!"
#define MSG_SEARCH_RECORD "Enter a keyword to search for a record on the playlist."
#define MSG_EMPTY_SEARCH "There are no songs matching the input keyword."
#define OPT_PLAY_IN_ORDER "0 - Play in order."
#define OPT_PLAY_RANDOM "1 - Play randomly."
#define OPT_PLAY_RECORD "2 - Play record."
#define OPT_ADD_RECORD "3 - Add record."
#define OPT_SEARCH_RECORD "4 - Search record."
#define OPT_LIST_RECORD "5 - List records."
#define OPT_EXIT "6 - Exit."
#define MAX_PLAYLIST 25
#define MAX_RECORD 20
#define MAX_MENU 6
typedef enum {PLAY_IN_ORDER=0,PLAY_RANDOM=1,PLAY_RECORD=2, ADD_RECORD=3, SEARCH_RECORD=4,LIST_RECORD=5,EXIT=6} first_choice_t;
typedef enum {ST_INPUT_ERROR=0,ST_EMPTY_LIST=1,ST_FULL_PLAYLIST=2,ST_ALREADY_IN=3,ST_WRONG_NAME=4,ST_RANDOM_ERR=5,ST_EMPTY_SEARCH=6,ST_EXIT=7,OK=8} status_t;
void initialize_array(char ** array);
char * select_record (char ** playList, int i);
status_t menu_limit(int choice);
void printMenu();
status_t player(char ** playList);
status_t playOrder(char** playList);
status_t validateChoice(int choice, char ** playList);
status_t playRandom(int max_rand,char ** playList);
status_t printPlaylist(char** playList);
void playRecord (char * record);
int limit_random(int max_random);
void cleanstdin();
status_t add_record (char * record,char ** playList);
status_t fill_playlist (char * record,char ** playList);
status_t check_repeat (char * record,char ** playList,int length);
status_t search_record (char * keyword, char ** playList);
int main()
{
/*string array which i'll initialize with 0s to fill with songs later.*/
char * playList [MAX_PLAYLIST];
status_t st= OK;
initialize_array(playList);
srand(time(NULL));
if((st=player(playList))!=OK)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
/*prints the main menu of the program*/
void printMenu(){
puts(OPT_PLAY_IN_ORDER);
puts(OPT_PLAY_RANDOM);
puts(OPT_PLAY_RECORD);
puts(OPT_ADD_RECORD);
puts(OPT_SEARCH_RECORD);
puts(OPT_LIST_RECORD);
puts(OPT_EXIT);
}
/*the program itself, depending on the input number continues with the selected function */
status_t player (char ** playList){
int record_choice,max_random,choice;
char aux[MAX_RECORD];
char * record;
char * keyword;
char * err_library[] = {MSG_INPUT_ERROR, MSG_EMPTY_LIST, MSG_FULL_LIST,MSG_ALREADY_IN,MSG_WRONG_NAME,MSG_RANDOM_ERR,MSG_EMPTY_SEARCH};
status_t st=OK;
do{
printMenu();
scanf("%d",&choice);
cleanstdin();
if((st =menu_limit(choice))!=OK){
fprintf(stderr, "%s\n",err_library[st]);
return st;
}
switch(choice)
{
case(PLAY_IN_ORDER):
{
if((st=playOrder(playList))!=OK){
fprintf(stderr,"%s \n", err_library[st]);
}
else
st = ST_EXIT;
break;
}
case(PLAY_RANDOM):
{
puts(MSG_RANDOM_LIST);
scanf("%d",&max_random);
cleanstdin();
if((st=playRandom(max_random,playList))!=OK){
fprintf(stderr,"%s\n",err_library[st]);
break;
}
st=ST_EXIT;
break;
}
case(PLAY_RECORD):
{
if((st=printPlaylist(playList))!=OK){
fprintf(stderr, "%s\n",err_library[st]);
break;
}
scanf("%d",&record_choice);
cleanstdin();
if((st=validateChoice(record_choice,playList))!=OK){
fprintf(stderr, "%s\n", err_library[st]);
break;
}
record = select_record(playList,record_choice);
playRecord(record);
st=ST_EXIT;
break;
}
case(ADD_RECORD):{
printf("%s \n",MSG_ADD_RECORD);
fgets(aux,MAX_RECORD,stdin);
aux[(strlen(aux)-1)]='\0';
record= aux;
if ((st=add_record(record,playList))!=OK)
fprintf(stderr,"%s \n",err_library[st]);
break;
}
case (SEARCH_RECORD):
puts(MSG_SEARCH_RECORD);
fgets(aux,MAX_RECORD,stdin);
keyword= aux;
if((st =search_record(keyword,playList))!=OK)
fprintf(stderr,"%s\n",err_library[st]);
break;
case (LIST_RECORD):
if((st=printPlaylist(playList))!=OK){
fprintf(stderr, "%s\n",err_library[st]);
return st;
}
break;
case(EXIT):
{
return ST_EXIT;
}
default:
{
fprintf(stderr,"%s\n",MSG_INPUT_ERROR);
return ST_EXIT;
}
}
}while (st != ST_EXIT);
return OK;
}
/*Checks that, having six functions, you don't put a 7*/
status_t menu_limit (int choice){
if (choice > MAX_MENU)
return ST_INPUT_ERROR;
return OK;
}
/*Plays the songs in the playlist in order*/
status_t playOrder(char ** playList){
int i;
char * record;
for(i=0;playList[i] != 0 && i <MAX_PLAYLIST; i++){
record = select_record(playList,i);
playRecord(record);
}
if(i == 0)
return ST_EMPTY_LIST;
return OK;
}
/*Checks that, having for example, 6 songs in the playlist, you don't put song n°7*/
status_t validateChoice(int choice,char ** playList){
int i;
for(i=0; playList[i] != 0 && i < MAX_PLAYLIST; i++);
if(choice > MAX_PLAYLIST || choice > i)
return ST_INPUT_ERROR;
return OK;
}
/*Plays the playlist randomly */
status_t playRandom(int max_random,char ** playList){
int i;
status_t st;
char * record;
if ((st = validateChoice(max_random,playList)) != OK){
return ST_RANDOM_ERR;
}
for(i=0;i<max_random;i++){
record = select_record(playList,limit_random(MAX_PLAYLIST));
playRecord(record);
}
return OK;
}
/*print current playlist*/
status_t printPlaylist(char ** playList){
int i;
for(i=0;playList[i] != 0 && i< MAX_PLAYLIST ;i++){
printf("%d -%s \n",i,playList[i]);
}
if (i == 0)
return ST_EMPTY_LIST;
return OK;
}
/*recieves an int and returns the corresponding song (this could be all inside of playrecord)*/
char * select_record (char ** playList, int i){
return playList[i];
}
/*given a string plays the record using mpg123 this function was provided by the one who thought the assignment*/
void playRecord (char * record){
char * cmd[3];
int pid = fork();
cmd[0]="mpg123";
cmd[1]=record;
cmd[2]=NULL;
if (!pid)
execvp(cmd[0],cmd);
waitpid(pid,NULL,0);
}
/*Initializes the array with 0s*/
void initialize_array(char ** playList){
int i;
for(i=0;i<MAX_PLAYLIST;i++){
playList[i]=0;
}
}
int limit_random(int max_random){
int number;
number = (rand()%(max_random+1));
return number;
}
void cleanstdin (void){
int c;
do
{
c=getchar();
}
while(c != '\n' && c != EOF);
}
/*procedures and validations to add a song into the playlsit.*/
status_t add_record (char * record,char ** playList){
status_t st;
char aux[90];
strcpy(aux,LIBRARY_DIRECTORY);
strcat(aux,record);
if (!access(aux, F_OK)){
if((st=fill_playlist(record,playList))!=OK)
return st;
}
else{
return ST_WRONG_NAME;
}
return OK;
}
/* once the user inputs a name, and after making some validations adds the song to the playlist(first position that doesn't have a "0" on it)*/
status_t fill_playlist (char * record,char ** playList){
int i;
status_t st;
char * aux;
aux = record;
for(i=0;playList[i] != 0 && i < MAX_PLAYLIST; i++){}
if (i == MAX_PLAYLIST)
return ST_FULL_PLAYLIST;
if((st=check_repeat(aux,playList,i))!=OK)
return st;
playList[i]=aux;
printf("%s\n",MSG_SUCCESFUL_ADD);
return OK;
}
/* Checks the songs which is about to be added isn't already in the playlist*/
status_t check_repeat (char * record,char ** playList,int length){
int i;
for (i=0; i < length;i++){
if(strcmp(record, playList[i])==0);
return ST_ALREADY_IN;
}
return OK;
}
/*After receiving a keyword checks any match with all songs in the playlist*/
status_t search_record (char * keyword, char ** playList){
int i,aux=0;
for (i=0; playList[i] != 0 && i < MAX_PLAYLIST; i++){
if(strstr(keyword, playList[i])!= NULL){
printf("%s\n",playList[i]);
aux++;
}
}
if(i==0)
return ST_EMPTY_LIST;
if(aux == 0)
return ST_EMPTY_SEARCH;
printf("%s%s\n",MSG_SEARCH,keyword);
return OK;
}
我很确定问题出在这个函数中:
status_t add_record (char * record,char ** playList){
status_t st;
char aux[90];
strcpy(aux,LIBRARY_DIRECTORY);
strcat(aux,record);
if (!access(aux, F_OK)){
if((st=fill_playlist(record,playList))!=OK)
return st;
}
else{
return ST_WRONG_NAME;
}
return OK;
}
/* once the user inputs a name, and after making some validations adds the song to the playlist(first position that doesn't have a "0" on it)*/
status_t fill_playlist (char * record,char ** playList){
int i;
status_t st;
char * aux;
aux = record;
for(i=0;playList[i] != 0 && i < MAX_PLAYLIST; i++){}
if (i == MAX_PLAYLIST)
return ST_FULL_PLAYLIST;
if((st=check_repeat(aux,playList,i))!=OK)
return st;
playList[i]=aux;
printf("%s\n",MSG_SUCCESFUL_ADD);
return OK;
}
/* Checks the songs which is about to be added isn't already in the playlist*/
status_t check_repeat (char * record,char ** playList,int length){
int i;
for (i=0; i < length;i++){
if(strcmp(record, playList[i])==0);
return ST_ALREADY_IN;
}
return OK;
}
最佳答案
fill_playlist (song, list)
如果您在到达 fill_playlist 时查看回溯,您会发现调用中的问题。要添加到播放列表中的歌曲不是唯一指针,而是指向存储在堆栈上的数据。解决此问题的最快方法是在 full_playlist 中执行此操作:
将 playList[i]=aux;
替换为 playList[i]=strdup(aux);
。
我还没有阅读其余代码的错误,但这是我能找到的最明显的错误。 (再次释放此字符串缓冲区,将返回的指针 strdup()
发送到 free()
。
关于c - Fgets 在每次调用时重写字符串数组位置 [0] 上的最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36815469/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!