Reputation: 75
#include <stdio.h>
#include <string.h>
void find_track(char *search_for);
char tracks[][80] = {
"I left my heart in Harvard Med School",
"Newark, Newark - a wonderful town",
"Dancing with a Dork",
"From here to maternity",
"The girl from Iwo Jima"
};
int main() {
char *to_search_str;
printf("Search for: ");
fgets(to_search_str, 80, stdin);
find_track(to_search_str);
return 0;
}
void find_track(char *search_for) {
int i;
for (i=0; i<5; i++) {
if (strstr(tracks[i], search_for)) {
printf("Track %d: '%s'\n", i, tracks[i]);
}
}
}
The program is supposed to search for a string in every string in the tracks
multi dimensional array but the strstr()
function in the find_track
is always returning null no matter the input (even if we input the a sub string of a string from tracks
multi dimensional array). I don't know why this is happening?
EDIT: After correction
#include <stdio.h>
#include <string.h>
void find_track(char *search_for);
char tracks[][80] = {
"I left my heart in Harvard Med School",
"Newark, Newark - a wonderful town",
"Dancing with a Dork",
"From here to maternity",
"The girl from Iwo Jima"
};
int main() {
char to_search_str[80];
printf("Search for: ");
fgets(to_search_str, 80, stdin);
to_search_str[strlen(to_search_str)-1] = '\0';
find_track(to_search_str);
return 0;
}
void find_track(char *search_for) {
int i;
for (i=0; i<5; i++) {
if (strstr(tracks[i], search_for)) {
printf("Track %d: '%s'\n", i, tracks[i]);
}
}
}
Upvotes: 1
Views: 282
Reputation: 7490
You aren't allocating to_search_str
pointer, the char *
pointer you pass to fgets
as the destination buffer. Being it actually uninitialized, this causes undefined behavior that normally ends with a program crash.
You just need to allocate it, statically or dynamically.
The simplest solution consists in just defining a static array in the stack:
#include <string.h>
#define LEN 80
int main() {
char to_search_str[LEN];
printf("Search for: ");
fgets(to_search_str, LEN, stdin);
/* Remove trailing newline from the string to search */
to_search_str[strcspn(to_search_str, "\n")] = 0;
find_track(to_search_str);
return 0;
}
The size of the array is 80 because you use this number as the size parameter in fgets
. Please note the use of a #define
for the constant 80, making possible to change it in a easier way.
The dynamic allocation in the heap involves the use of malloc()
function (and free()
as soon as the array is not needed anymore):
#include <string.h>
#define LEN 80
int main() {
char * to_search_str = malloc(LEN);
printf("Search for: ");
fgets(to_search_str, LEN, stdin);
/* Remove trailing newline from the string to search */
to_search_str[strcspn(to_search_str, "\n")] = 0;
find_track(to_search_str);
free(to_search_str);
return 0;
}
Note: since fgets
retains trailing newline ``\n'` in the output buffer, we have to remove it. I used the clever oneliner solution described here.
Upvotes: 1
Reputation: 311146
This code snippet in main
char *to_search_str;
printf("Search for: ");
fgets(to_search_str, 80, stdin);
invokes undefined behavior because the pointer to_search_str
is not initialized and has indeterminate value.
It seems you at least mean
char to_search_str[80];
printf("Search for: ");
fgets(to_search_str, 80, stdin);
The function fgets
can append the new line character '\n'
to the entered string.
You need to remove it for example the following way
to_search_str[ strcspn( to_search_str, "\n" ) ] = '\0';
The function find_track
should be declared at least like
void find_track( const char *search_for);
Though it is a bad idea when a function definition relies on global variables.
Also the approach of finding relevant strings is not good. For example the user can enter a string that contains only one character 'a'
. In this case all records will satisfy the condition. You should check that the searched string forms a word (a sequence of characters separated by spaces) in a string in the array.
Upvotes: 0
Reputation: 134396
Most likely the issue with input via fgets()
.
You are reading into an uninitialized pointer to_search_str
, which does not point to a valid memory location. In this case, you can simply change this to an array, like char to_search_str[80] = {0};
and get done with it.
You need to trim the trailing newline that's stored in the input buffer.
From the man page, (emphasis mine)
fgets()
reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after anEOF
or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0'
) is stored after the last character in the buffer.
A quick way of getting that done is to_search_str[strcspn(to_search_str, "\n")] = 0;
, but there are more robust ways mentioned in this other answer
Upvotes: 1
Reputation: 9814
char *to_search_str;
is an uninitialized pointer, writing to it will result in undefined behavior. You have to allocate memory or use an array instead char to_search_str[100];
for example.
Also don't forget that fgets
will also read the newline into the buffer, which you have to remove.
Upvotes: 0