How do I display the searched string on the screen? - c

So, what I'm trying to do, is have the user search for a cheese and having it display it on the screen. I'm having trouble with the latter. I cant seem to display the string, but my code still runs. Here is my code:
#include<stdio.h>
#include<string.h>
char cheeses[][20] = {
"Cheddar",
"White Cheddar",
"Colby Jack",
"Gouda",
"Blue Cheese",
"Gorgonzola",
"Asiago",
"Limburger",
"Feta",
"Brie",
"Goat",
};
void find_cheese(const char *search_for)
{
int i;
for (i = 0; i < 5; i++) {
if (strstr(cheeses[i], search_for))
printf("Cheese %i: '%s'\n", i, cheeses[i]);
}
}
int main()
{
char search_for[20];
printf("Search for: ");
fgets(search_for, 20, stdin);
find_cheese(search_for);
return 0;
}
So what do I do in this case. I want it so that you can type in, "Lim," and have it display Limburger (in the future it will be able to display info on the cheese). How will I do this?

It looks okay, but you only search through the 5 first, and Limburger is too close to the end of the list.
This type of code is better to solve with a "sentinel", i.e. a special marker that is used to signify that the list has ended. For strings, you can represent the array as an array of pointers to strings rather than a fixed-size array, and then using NULL as the sentinel is pretty natural.
The array would become:
const char *cheeses[] = { "Cheddar", "White Cheddar", "Colby Jack",
/* ... rest of the cheeses ... */
NULL
};
then you can write the search loop like so:
int i;
for( i = 0; cheeses[i] != NULL; ++i )
{
/* Test and handling code here, against cheeses[i] just like before. */
}

Related

how to remove certain words from a line of text in c

I got my code working to an extent, but I need some more help. If I needed to remove the word "an", from sentence: "I ate an apple whilst looking at an ape.", it only removes the first "an" and not the second, how do I repeat the loop so it deletes all "an"s? I need the final sentence, after the code has been ran, to be: "I ate apple whilst looking at ape.". That is the goal im trying to achieve
Sorry for not including the code.
Here it is:
#include "RemoveFromText.h"
#include <stdlib.h>
#include <string.h>
int findFirstSubstring(char textToChange[], char removeThis[])
{
int size = strlen(textToChange);
int subStringLength = strlen(removeThis);
for(int i=0; i<size; i++)
{
if(textToChange[i] == removeThis[0])
{
int j = 0;
while(textToChange[i+j] == removeThis[j])
{
j++;
if(j==subStringLength)
{
return i;
}
}
}
}
return -1;
}
void removeFromText( char textToChange[], char removeThis[])
{
int textLength = strlen(textToChange);
if(findFirstSubstring(textToChange, removeThis) >= 0)
{
int subStringIdx = findFirstSubstring(textToChange, removeThis);
int loopVariabele = 0;
for(loopVariabele = subStringIdx; loopVariabele<textLength; loopVariabele++)
{
textToChange[loopVariabele] = textToChange[loopVariabele + strlen(removeThis)];
}
}
}
Leveraging 'strstr', and 'memmove' standard "C" library functions
// Remove all occurences of 'source' from 'message'.
void removeAll(char *message, char *source)
{
int len = strlen(source) ;
for (char *x = message ; x=strstr(x, source) ; ) {
// Copy everything after 'source', including terminating nul.
memmove(x, x+len, strlen(x+len)+1) ;
} ;
}
Notes:
that solution that not properly address the trailing space(s) after a word. This can be addressed by chaning the 'memmove'.
Probably make sense to make the function return the number of substitutions, or some other meaningful result

Changing char[] in C

I looking for a answer and can't find nowhere. I hope you'll help me. I write a simple app which include struct with a name of worker and . But when i want to change value of name i can't do it. I don't know why. Maybe you can't help me or you know another ways to do it? My code:
struct workers {
char name[256]="no";
int pay=-1;
};
void addOne(struct workers work[20]) {
char name[256];
int i=0;
for (i = 0; work[i].name != "no"; i++) {}
printf_s("Enter name of worker: ");
scanf_s("%s", &name);
//-----error here-----
work[i].name = name;
}
int main()
{
int i;
struct workers work[20];
for (i = 0;i < 20; i++) {
if (work[i].name != "no") {
work[i].pay = 100 * i;
}
}
for (i = 0; i < 20; i++) {
printf_s("%s\t%d\n", work[i].name, work[i].pay);
}
return 0;
}
work[i].name = name;
The above line is where the problem is.
Change as below:
snprintf( work[i].name, sizeof(work[i].name), "%s", name);
What you have done is trying to change the base pointer of the array and not the name.
Also there were few more errors in the code, pls resolve them.
It is not possible to set default values to structure as you have done in C.
You have to write code to init each array instance name variable with "no" in a loop and then use one of the string comparison functions to compare the strings. And then call your addOne.

Strange Behavior with String Arrays in C

I've been having some difficulties with strings in C - especially when it comes to File I/O. I've looked through some previous threads to see how to make string arrays in C, and I have come up with this.
void CreateBiomes()
{
const int STRING_LENGTH = 32;
const int BIOME_COUNT = 63;
const char *biomes[BIOME_COUNT][STRING_LENGTH+1] = {"beaches", "birch_forest", "birch_forest_hills", "cold_beach", "deep_ocean", "desert", "desert_hills", "extreme_hills", "extreme_hills_with_trees", "forest", "forest_hills", "frozen_ocean", "frozen_river", "hell", "ice_flats", "ice_mountains", "jungle", "jungle_edge", "jungle_hills", "mesa", "mesa_clear_rock", "mesa_rock", "mushroom_island", "mushroom_island_shore", "mutated_birch_forest", "mutated_birch_forest_hills", "mutated_desert", "mutated_extreme_hills", "mutated_extreme_hills_with_trees", "mutated_forest", "mutated_ice_flats", "mutated_jungle", "mutated_jungle_edge", "mutated_mesa", "mutated_mesa_clear_rock", "mutated_mesa_rock", "mutated_plains", "mutated_redwood_taiga", "mutated_redwood_taiga_hills", "mutated_roofed_forest", "mutated_savanna", "mutated_savanna_rock", "mutated_swampland", "mutated_taiga", "mutated_taiga_cold", "ocean", "plains", "redwood_taiga", "redwood_taiga_hills", "river", "roofed_forest", "savanna", "savanna_rock", "sky", "smaller_extreme_hills", "stone_beach", "swampland", "taiga", "taiga_cold", "taiga_cold_hills", "taiga_hills", "void"};
for(int i = 0; i <= BIOME_COUNT; i++)
{
printf("%s\n", *biomes[i]);
}
return;
}
The issue is - this code only works for "beaches" and "mutated_mesa" before the program crashes. Everything compiles great, it just won't process any of the other strings I've listed in my array, instead, it prints a (null). Why is this?
Try replacing the declaration
const char *biomes[BIOME_COUNT][STRING_LENGTH+1]
as follows.
const char biomes[BIOME_COUNT][STRING_LENGTH+1]
Your array was a 2-D array of pointers, and, you indexed one too many in the printf loop.
I have changed this to a 1-D array of pointers, and also removed the hard coded sizes. Instead I replaced the last string "void" with a NULL pointer, and used that to control the loop.
#include <stdio.h>
void CreateBiomes(void)
{
const char *biomes[] = {"beaches", "birch_forest", "birch_forest_hills", "cold_beach", "deep_ocean", "desert", "desert_hills", "extreme_hills", "extreme_hills_with_trees", "forest", "forest_hills", "frozen_ocean", "frozen_river", "hell", "ice_flats", "ice_mountains", "jungle", "jungle_edge", "jungle_hills", "mesa", "mesa_clear_rock", "mesa_rock", "mushroom_island", "mushroom_island_shore", "mutated_birch_forest", "mutated_birch_forest_hills", "mutated_desert", "mutated_extreme_hills", "mutated_extreme_hills_with_trees", "mutated_forest", "mutated_ice_flats", "mutated_jungle", "mutated_jungle_edge", "mutated_mesa", "mutated_mesa_clear_rock", "mutated_mesa_rock", "mutated_plains", "mutated_redwood_taiga", "mutated_redwood_taiga_hills", "mutated_roofed_forest", "mutated_savanna", "mutated_savanna_rock", "mutated_swampland", "mutated_taiga", "mutated_taiga_cold", "ocean", "plains", "redwood_taiga", "redwood_taiga_hills", "river", "roofed_forest", "savanna", "savanna_rock", "sky", "smaller_extreme_hills", "stone_beach", "swampland", "taiga", "taiga_cold", "taiga_cold_hills", "taiga_hills",
NULL };
for(int i = 0; biomes[i] != NULL; i++) { // changed loop control
printf("%s\n", biomes[i]); // changed argument passed
}
}
int main(void){
CreateBiomes();
return 0;
}
Please note that this function won't do much good, because biomes, a local variable, will not be accessible after the function returns.
Try this way, your code should work.
void CreateBiomes()
{
int BIOME_COUNT = 63;
char *biomes[]= {"beaches", "birch_forest", "birch_forest_hills", "cold_beach", "deep_ocean", "desert", "desert_hills", "extreme_hills", "extreme_hills_with_trees", "forest", "forest_hills", "frozen_ocean", "frozen_river", "hell", "ice_flats", "ice_mountains", "jungle", "jungle_edge", "jungle_hills", "mesa", "mesa_clear_rock", "mesa_rock", "mushroom_island", "mushroom_island_shore", "mutated_birch_forest", "mutated_birch_forest_hills", "mutated_desert", "mutated_extreme_hills", "mutated_extreme_hills_with_trees", "mutated_forest", "mutated_ice_flats", "mutated_jungle", "mutated_jungle_edge", "mutated_mesa", "mutated_mesa_clear_rock", "mutated_mesa_rock", "mutated_plains", "mutated_redwood_taiga", "mutated_redwood_taiga_hills", "mutated_roofed_forest", "mutated_savanna", "mutated_savanna_rock", "mutated_swampland", "mutated_taiga", "mutated_taiga_cold", "ocean", "plains", "redwood_taiga", "redwood_taiga_hills", "river", "roofed_forest", "savanna", "savanna_rock", "sky", "smaller_extreme_hills", "stone_beach", "swampland", "taiga", "taiga_cold", "taiga_cold_hills", "taiga_hills", "void"};
int i;
for(i = 0; i < BIOME_COUNT-1; i++)
{
printf("%s\n", biomes[i]);
}
return;
}

Printing an array of structs in C

I'm trying to print an array of structs that contain two strings. However my print function does not print more than two indices of the array. I am not sure why because it seems to me that the logic is correct.
This is the main function
const int MAX_LENGTH = 1024;
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
} Song;
void getStringFromUserInput(char s[], int maxStrLength);
void printMusicLibrary(Song library[], int librarySize);
void printMusicLibraryTitle(void);
void printMusicLibrary (Song library[], int librarySize);
void printMusicLibraryEmpty(void);
int main(void) {
// Announce the start of the program
printf("%s", "Personal Music Library.\n\n");
printf("%s", "Commands are I (insert), S (sort by artist),\n"
"P (print), Q (quit).\n");
char response;
char input[MAX_LENGTH + 1];
int index = 0;
do {
printf("\nCommand?: ");
getStringFromUserInput(input, MAX_LENGTH);
// Response is the first character entered by user.
// Convert to uppercase to simplify later comparisons.
response = toupper(input[0]);
const int MAX_LIBRARY_SIZE = 100;
Song Library[MAX_LIBRARY_SIZE];
if (response == 'I') {
printf("Song name: ");
getStringFromUserInput(Library[index].songName, MAX_LENGTH);
printf("Artist: ");
getStringFromUserInput(Library[index].artist, MAX_LENGTH);
index++;
}
else if (response == 'P') {
// Print the music library.
int firstIndex = 0;
if (Library[firstIndex].songName[firstIndex] == '\0') {
printMusicLibraryEmpty();
} else {
printMusicLibraryTitle();
printMusicLibrary(Library, MAX_LIBRARY_SIZE);
}
This is my printing the library function
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
printf("\n");
bool empty = true;
for (int i = 0; (i < librarySize) && (!empty); i ++) {
empty = false;
if (library[i].songName[i] != '\0') {
printf("%s\n", library[i].songName);
printf("%s\n", library[i].artist);
printf("\n");
} else {
empty = true;
}
}
}
I think the problem is caused due to setting : empty = true outside the for loop and then checking (!empty) which will evaluate to false. What I am surprised by is how is it printing even two indices. You should set empty = false as you are already checking for the first index before the function call.
The logic has two ways to terminate the listing: 1) if the number of entries is reached, or 2) if any entry is empty.
I expect the second condition is stopping the listing before you expect. Probably the array wasn't built as expected (I didn't look at that part), or something is overwriting an early or middle entry.
you gave the definition as:
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
}Song;
the later, you write if (library[i].songName[i] != '\0') which really seems strange: why would you index the songname string with the same index that the lib?
so I would naturally expect your print function to be:
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
for (int i = 0; i < librarySize; i ++) {
printf("%s\n%s\n\n", library[i].songName,
library[i].artist);
}
}
note that you may skip empty song names by testing library[i].songName[0] != '\0' (pay attention to the 0), but I think it would be better not to add them in the list (does an empty song name make sens?)
(If you decide to fix that, note that you have an other fishy place: if (Library[firstIndex].songName[firstIndex] == '\0') with the same pattern)

User entered string run a particular function in c

Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !

Resources