Чего мне не хватает в этом использовании fgets?
Если я запускаю приведенный ниже код с помощью scanf, он возвращает строку, если она находится в массиве track. Согласно книге Head First C, это должно работать с fgets, но ничего не возвращает для меня:
#include <stdio.h>
#include <string.h>
#define MAX 80
char tracks[][MAX] = {
"The Girl from Ipanema",
"Here Comes the Sun",
"Wonderwall",
"You Belong To Me",
"Everlong",
};
void find_track(char search_for[])
{
int i = 0;
for(i = 0; i < 5; i++) {
if(strstr(tracks[i], search_for)) {
printf("Track %d: %s\n", i, tracks[i]);
}
}
}
int main()
{
char search_for[MAX];
printf("Search for: ");
//scanf("%79s", search_for);
fgets(search_for, MAX, stdin);
find_track(search_for);
return 0;
}
Вход выглядит следующим образом:
./tracks
Search for:
Here
Ничего не произошло
2 ответа
Это наверное потому что fgets
также будет читать новую строку, т.е. '\n'
, Более подробно:
Если вы печатаете Girl<enter>
затем search_for
будет содержать символы: 'G' 'i' 'r' 'l'
'\n'
Тем не менее, ваш tracks
только содержать 'G' 'i' 'r' 'l'
без '\n'
,
Следовательно, вы не найдете подходящей подстроки.
Попробуйте изменить:
fgets(search_for, MAX, stdin);
в
fgets(search_for, MAX, stdin);
if (strlen(search_for) > 0) search_for[strlen(search_for)-1] = '\0';
убрать завершающий перевод строки
Редактировать на основе комментариев
Это правда, что (в зависимости от вашей ОС / среды) входной поток может быть завершен без перевода строки (ctrl-z, ctrl-d в некоторых системах). Если это сделано, приведенный выше код недостаточен. Требуется дополнительная проверка, например:
if (strlen(search_for) > 0 && search_for[strlen(search_for)-1] == '\n')
search_for[strlen(search_for)-1] = '\0';
чтобы убедиться, что только символ перевода строки преобразуется в завершение строки.
Вы также можете использовать функцию memcpy, чтобы избавиться от новой строки.
Функция библиотеки C void *memcpy(void *str1, const void *str2, size_t n) копирует n символов из области памяти str2 в область памяти str1.
fgets(s, MAX, stdin);
memcpy(search_for, s, strlen(s)-1);
find_track(search_for);
Вы также можете добавить некоторую обработку ошибок.