Edit - Sorry, I misread - if you're not allowed to read from a file, then modify the fgets line to read from stdin instead of pfile, and omit all fopen, fclose stuff.
void read_in_string_stdin (char pangram[]){
printf("please enter the pangram\n");
if (fgets(pangram, 50, stdin) == NULL) {
/* stuff */
}
and to compile and run:
gcc -Wall -o zpg pangram.c
./zpg < pangram_file.txt
For reading in from a file, you'll want to open a file using fopen, read with either fscanf or fgets, check the return value, and close the file with fclose.
If you use fscanf with the %s string, it will stop at the first whitespace encountered - hence use of the %[^.] or %[^\n] formatting flags instead, to read until the first period or newline, respectively.
If you use fgets, it will read until a newline or a limiting number of characters have been read.
Also, you do have an assignment vs. equality-testing problem in the if loop.
Stylistically, there are also several issues (not error-producing on the computer's part, but error-prone for the reader) around the naming of variables and functions.
- Name functions by what they do, not by metadata such as problem number.
- The
count_char_occur variable above is misleading, since it doesn't count occurrences of the sought char.
- It's best to keep
for-loop conditions as self-contained as possible, in case of later copy/paste (e.g. "I've pasted this elsewhere and ... what was the initial condition again??")
Here's a working and prettified version:
void count_occurrences(char char_to_find) {
/* Problem 01 function. */
char pangram[50];
FILE *pfile = fopen("pangram_file.txt", "r"); /* Opens in read-only mode. */
if (pfile == NULL) {
printf("could not open file. Exiting now.\n");
exit(EXIT_FAILURE);
}
if (fgets(pangram, 50, pfile) == NULL) {
printf("could not read string from file. Exiting now.\n");
exit(EXIT_FAILURE);
}
fclose(pfile);
printf("Now I have string |%s|\n", pangram); /* Check that you have what you think */
int string_pos; // "count_char_occur" was a misleading variable name
int occurrences_found = 0;
for (string_pos = 0; string_pos < strlen(pangram);string_pos++) {
if(pangram[string_pos] == char_to_find) { /* --- Assignment vs. Equality --- */
printf("The character %c has been found, at position %i. \n", pangram[string_pos], string_pos);
occurrences_found++;
}
}
/* Keep the user in the loop about what happened - reduce assumptions! */
if (occurrences_found == 0)
printf("The character %c was not found.\n\n", char_to_find);
else
printf("The character %c was found %i times in total.\n\n", char_to_find, occurrences_found);
}
Now that you see this, this guy has a lot of responsibility, and it makes more sense to delegate one duty per function, doesn't it? Have one function handle the reading-in of the string, and another to count occurrences. Then you also aren't repeating the work of reading in the string for every different char you want to count in the same string.
void read_in_string (char pangram[]){
FILE *pfile = fopen("pangram_file.txt", "r");
/* .... intervening lines as in above .... */
printf("Now I have string |%s|\n", pangram);
}
void count_occurrences_only (char mystring[], char char_to_find) {
int string_pos;
/* .... intervening lines as in above, through end of count_occurrences .... */
}
int main(void) {
char pangram[50];
read_in_string(pangram);
count_occurrences_only(pangram, 'e');
count_occurrences_only(pangram, 'x');
return 0;
}
==on this line:if(pangram[count_char_occur] = char_to_find)rewind(stdin);myprogram_bin < pangram.txtis not having the program read a .txt file. The program is still reading fromstdin. The end effect of using<is similar for the first pass but code does not get to rewindstdinin general. Change code to read from aFILE*opened viafopen(pangram.txt,...).eby coincidence; thescanf()reads the wordTheand the faulty comparison counts each character in the string. The second call toscanf()readsquickand then counts 5 characters. You need to think about reading the whole line at once and scanning that. Either do this first and then scan the string for the character you're looking for, or rewind the file between letters. Generally, reading from a file is slow so you try to avoid reading a file more than once. Also note that you cannot usefully rewind standard input if the input is the terminal./dev/ttyis not rewindable either).