Segmentation Fault Error (C) - c

I am currently writing a program that is supposed to receive input from a text file and output statistics about the text such as the number of letters, size of words and how often they occur, and how many times each word occurs. However, every time I run the program, I get a segmentation fault error. The program runs until I hit the line Letter Count Analysis. The I receive the segmentation fault error. Here is some sample text:
1
Hello my name is Bob
I live in Canada
The number represents how many lines are supposed to be read. What should I do to correct my issue? I am very new to programming so I'm sure it is something basic.
#include <stdio.h>
#include <string.h>
#define MAX_LINE_LENGTH 80
#define MAX_WORD_LENGTH 20
#define MAX_LINES 10
void letterAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int wordLengthAnalysis(char [][MAX_LINE_LENGTH], int lineTotal, int wordLength);
void wordAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int main (void){
int lineTotal, wordSize;
char text[lineTotal][MAX_LINE_LENGTH];
char n[1];
fgets(n, 10, stdin);
lineTotal = n[0] - '0';
for(int i = 0; i < lineTotal; i++){
fgets(text[i], MAX_WORD_LENGTH, stdin);
}
printf("\n***Letter count analysis***\n");
letterAnalysis(text, lineTotal);
printf("\n***Word length analysis***\n");
for (int i = 1; i <= MAX_WORD_LENGTH; i++){
wordSize = wordLengthAnalysis(text, lineTotal, i);
if (wordSize == 1){
printf("\n%-2d\tword of length %d", wordSize, i);
}
else{
printf("\n%-2d\twords of length %d", wordSize, i);
}
}
printf("\n\n***Word analysis***\n");
wordAnalysis(text, lineTotal);
return 0;
}
void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
int alphabet[26] = {0};
for (int i = 0; i < lineTotal; i++){
for(int j = 0; j < MAX_LINE_LENGTH; j++){
switch(text[i][j]){
case 'A': case 'a':
alphabet[0]++;
break;
case 'B': case 'b':
alphabet[1]++;
break;
case 'C': case 'c':
break;
alphabet[2]++;
case 'D': case 'd':
alphabet[3]++;
break;
case 'E': case 'e':
alphabet[4]++;
break;
case 'F': case 'f':
alphabet[5]++;
break;
case 'G': case 'g':
alphabet[6]++;
break;
case 'H': case 'h':
alphabet[7]++;
break;
case 'I': case 'i':
alphabet[8]++;
break;
case 'J': case 'j':
alphabet[9]++;
break;
case 'K': case 'k':
alphabet[10]++;
break;
case 'L': case 'l':
alphabet[11]++;
break;
case 'M': case 'm':
alphabet[12]++;
break;
case 'N': case 'n':
alphabet[13]++;
break;
case 'O': case 'o':
alphabet[14]++;
break;
case 'P': case 'p':
alphabet[15]++;
break;
case 'Q': case 'q':
alphabet[16]++;
break;
case 'R': case 'r':
alphabet[17]++;
break;
case 'S': case 's':
alphabet[18]++;
break;
case 'T': case 't':
alphabet[19]++;
break;
case 'U': case 'u':
alphabet[20]++;
break;
case 'V': case 'v':
alphabet[21]++;
break;
case 'W': case 'w':
alphabet[22]++;
break;
case 'X': case 'x':
alphabet[23]++;
break;
case 'Y': case 'y':
alphabet[24]++;
break;
case 'Z': case 'z':
alphabet[25]++;
break;
}
}
}
for(int i = 0; i <= 25; i++){
printf("%c: \t%d\n",'a' + i, alphabet[i]);;
}
}
int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength){
int sentenceLength;
int counter, wordSize = 0;
for(int i = 0; i < lineTotal; i++){
sentenceLength = strlen(&text[i][0]);
for(int j = 0; j < sentenceLength + 2; j++){
if(text[i][j] == ' '){
if(counter == wordLength){
++wordSize;
counter = 0;
}
else{
counter = 0;
}
}
else{
counter++;
}
}
}
return wordSize;
}
void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
char maxWords[800];
char word[MAX_LINE_LENGTH], word2[MAX_WORD_LENGTH], *ptrText, *ptrTextCounter;
int counter, textCounter = 0;
int sentenceLength, wordTracker;
int lineFlag;
for(int i = 0; i < lineTotal; i++){
ptrText = &text[i][0];
sentenceLength = strlen(ptrText);
counter = 0;
for (int j = 0; j < sentenceLength + 1; j++){
wordTracker = 1;
if (text[i][j] == ' ' ){
if (counter != 0){
sprintf(word, "%.*s", counter, ptrText);
ptrTextCounter = &text[i][j+1];
lineFlag = j;
if(strstr(maxWords, word) == NULL){
for (int k = i; k < lineTotal; k++){
textCounter = 0;
if (lineFlag == j){
ptrTextCounter = &text[i][j+1];
}
else{
lineFlag = 0;
ptrTextCounter = &text[i][j+1];
}
for ( ; lineFlag < sentenceLength; lineFlag++){
if(text[k][lineFlag] == ' '){
if (textCounter != 0){
if(textCounter == counter){
sprintf(word2, "%.*s", textCounter, ptrTextCounter);
if(strcmp(word, word2) == 0){
wordTracker++;
}
}
ptrTextCounter = &text[k][lineFlag];
textCounter = 0;
}
else{
ptrTextCounter = &text[k][lineFlag+1];
}
}
else{
textCounter++;
}
}
}
if(wordTracker == 1){
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
else{
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
}
strcat(maxWords, word);
ptrText = &text[i][j+1];
counter = 0;
}
else{
ptrText = &text[i][j+1];
}
}
else{
counter++;
}
}
}
}

I get a couple of warnings:
main.c:17:14: warning: variable length array used [-Wvla]
char text[lineTotal][MAX_LINE_LENGTH];
^
main.c:17:15: warning: variable 'lineTotal' is uninitialized when used here [-Wuninitialized]
char text[lineTotal][MAX_LINE_LENGTH];
^~~~~~~~~
You haven't initialized lineTotal but are using it. This causes undefined behavior.
main.c:64:21: warning: code will never be executed [-Wunreachable-code]
alphabet[2]++;
^~~~~~~~
Your break; is likely misplaced.
main.c:152:20: warning: variable 'counter' may be uninitialized when used here [-Wconditional-uninitialized]
if(counter == wordLength){
^~~~~~~
Again, you're using a potentially uninitialized variable.
Also:
char n[1];
fgets(n, 10, stdin);
Your array has one element but you tell fgets it can access up to n[10].
Hint (if it wasn't obvious already): never program C without warnings.

Related

seeking combinations (strstr) of letters in external file

I have a task to make smth like t9 like it was in old phones (number can also mean some combination of letters). For example, if user run it this way ./t9search 23 < list.txt, program should return numbers which has this combination of digits or letters that corresponds to them (in this case a,b,c and d,e,f). It's also forbidden to work with dynamic memory(malloc, free) and functions with algorithms (qsort, lsearch etc). Format of information in file is "name\n number\n name\n number\n...".
The loop doesn't work correctly but I can't find a mistake. The program should return {Name}, {number}but it return only numbers.
The code is:
`
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FULFILLED 1
#define NOT_FULFILLED 0
int main(int argc, char **argv)
{
char line[99];
int line_no = -1;
int size = strlen(argv[1]);
char letters[size][5];
int total_combinations = 1;
char combinations[total_combinations][size + 1];
int current_combination[size];
int check_name = NOT_FULFILLED;
char name[99];
for(int i = 0; argv[1][i]; i++)
{
switch(argv[1][i]) //cases according to input
{
case '0':
strcpy(letters[i], "+");
break;
case '2':
strcpy(letters[i], "abc");
break;
case '3':
strcpy(letters[i], "def");
break;
case '4':
strcpy(letters[i], "ghi");
break;
case '5':
strcpy(letters[i], "jkl");
break;
case '6':
strcpy(letters[i], "mno");
break;
case '7':
strcpy(letters[i], "pqrs");
break;
case '8':
strcpy(letters[i], "tuv");
break;
case '9':
strcpy(letters[i], "wxyz");
break;
}
total_combinations *= strlen(letters[i]); //number of combinations of letters from array elements
}
for (int i = 0; i < size; i++)
{
current_combination[i] = 0;
}
int k = 0;
while (k < total_combinations)
{
for (int set_idx = 0; set_idx < size; set_idx++)
{
int letter_idx = current_combination[set_idx];
combinations[k][set_idx] = letters[set_idx][letter_idx];
}
combinations[k][size] = '\0';
for(int i = size - 1; i >= 0; i--)
{
current_combination[i]++;
if (current_combination[i] == strlen(letters[i]))
{
current_combination[i] = 0;
}
else
{
break;
}
}
k++;
}
printf("%c\n", sizeof(combinations)/sizeof(combinations[0]));
while(fgets(line, sizeof(line), stdin))
{
line_no++;
if (line_no % 2 == 0) //even lines (names)
{
name[99] = line; //variable to use name with number
for (int i = 0; i < total_combinations; i++) //for each combination from array with combinations
{
if (strstr(line, combinations[i])) //if combination is a substring of a string
{
check_name = FULFILLED;
}
}
}
else if (line_no % 2 == 1) //odd lines (numbers)
{
if (check_name == FULFILLED || strstr(line, argv[1])) // if there's name that corresponds with input OR input is a substring of a string
{
printf("%s, %s", name, line);
check_name = NOT_FULFILLED;
}
}
}
}
`
I've tried to change the way of checking names:
if (line_no % 2 == 0)
{
for (int j = 0; j <= strlen(letters); j++)
{
char let = getchar();
for (int i = 0; i < strlen(line); i++)
{
if (letters[j] == line[i])
{
check_name = FULFILLED;
continue;
}
else if (letters[j] != line [i])
{
break;
}
}
}
}
Sure I didn't reach success. So I'd be extremely grateful for any help.
Arrays do not resize reflectively when the variables used to create them change. They are sized permanently at the time of their initialization. The following
int total_combinations = 1;
char combinations[total_combinations][size + 1];
/* ... */
total_combinations *= strlen(letters[i]);
does not cause combinations to grow as total_combinations does. Move the definition of combinations to after total_combinations has been fully computed.
The following attempts to assign a char * to a char, and also indexes name out of bounds.
name[99] = line;
As done previously, use strcpy to copy strings.
Note that, if found and if there is room in the buffer, fgets stores the newline character in the buffer, so
printf("%s, %s", name, line);
will very likely print staggered output, like
Alice
, 5551234567
A cursory refactoring:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *remove_newline(char *string)
{
if (string)
string[strcspn(string, "\n")] = '\0';
return string;
}
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "usage: %s t9_sequence\n", argv[0]);
return EXIT_FAILURE;
}
int size = strlen(argv[1]);
char letters[size][5];
int total_combinations = 1;
int current_combination[size];
for (int i = 0; argv[1][i]; i++) {
switch (argv[1][i]) {
default:
fprintf(stderr, "Invalid input: \"%c\"\n", argv[1][i]);
return EXIT_FAILURE;
case '0':
strcpy(letters[i], "+");
break;
case '2':
strcpy(letters[i], "abc");
break;
case '3':
strcpy(letters[i], "def");
break;
case '4':
strcpy(letters[i], "ghi");
break;
case '5':
strcpy(letters[i], "jkl");
break;
case '6':
strcpy(letters[i], "mno");
break;
case '7':
strcpy(letters[i], "pqrs");
break;
case '8':
strcpy(letters[i], "tuv");
break;
case '9':
strcpy(letters[i], "wxyz");
break;
}
total_combinations *= strlen(letters[i]);
}
memset(current_combination, 0, sizeof current_combination);
char combinations[total_combinations][size + 1];
for (int k = 0; k < total_combinations; k++) {
for (int set_idx = 0; set_idx < size; set_idx++) {
int letter_idx = current_combination[set_idx];
combinations[k][set_idx] = letters[set_idx][letter_idx];
}
combinations[k][size] = '\0';
for (int i = size - 1; i >= 0; i--) {
current_combination[i]++;
if (current_combination[i] != strlen(letters[i]))
break;
current_combination[i] = 0;
}
}
char name[128];
char number[128];
while (1) {
if (!fgets(name, sizeof name, stdin))
break;
if (!fgets(number, sizeof number, stdin))
break;
int found = 0;
for (int i = 0; i < total_combinations; i++) {
if (strstr(name, combinations[i])) {
found = 1;
break;
}
}
if (found || strstr(number, argv[1]))
printf("%s, %s\n", remove_newline(name), remove_newline(number));
}
}

C Program Incorrect Output

I am currently writing a program that is supposed to receive input from a text file and output statistics about the text such as the number of letters, size of words and how often they occur, and how many times each word occurs. However, every time I run the program, the wordLengthAnalysis does not produce the correct output. The other two run perfectly. Here is some sample text (The number represents how many lines are supposed to be read):
1
Hello my name is Bob
I live in Canada
Usually it is only off by one number. What should I do to correct my issue? I am very new to programming so I'm sure it is something basic.
#include <stdio.h>
#include <string.h>
#define MAX_WORD_LENGTH 20
#define MAX_LINES 10
#define MAX_LINE_LENGTH 80
void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal);
int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength);
void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal);
int main (void){
int lineTotal, wordSize;
scanf("%d\n", &lineTotal);
char text[lineTotal][MAX_LINE_LENGTH];
for(int i = 0; i < lineTotal; i++){
gets(text[i]);
}
printf("\n***Letter count analysis***\n");
letterAnalysis(text, lineTotal);
printf("\n***Word length analysis***\n");
for (int i = 1; i < 21; i++){
wordSize = wordLengthAnalysis(text, lineTotal, i);
if (wordSize == 1){
printf("\n%-2d\tword of length %d", wordSize, i);
}
else if (wordSize == 0){}
else{
printf("\n%-2d\twords of length %d", wordSize, i);
}
}
printf("\n\n***Word analysis***\n");
wordAnalysis(text, lineTotal);
return 0;
}
void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
int alphabet[26] = {0};
for (int i = 0; i < lineTotal; i++){
for(int j = 0; j < MAX_LINE_LENGTH; j++){
switch(text[i][j]){
case 'A': case 'a':
alphabet[0]++;
break;
case 'B': case 'b':
alphabet[1]++;
break;
case 'C': case 'c':
alphabet[2]++;
break;
case 'D': case 'd':
alphabet[3]++;
break;
case 'E': case 'e':
alphabet[4]++;
break;
case 'F': case 'f':
alphabet[5]++;
break;
case 'G': case 'g':
alphabet[6]++;
break;
case 'H': case 'h':
alphabet[7]++;
break;
case 'I': case 'i':
alphabet[8]++;
break;
case 'J': case 'j':
alphabet[9]++;
break;
case 'K': case 'k':
alphabet[10]++;
break;
case 'L': case 'l':
alphabet[11]++;
break;
case 'M': case 'm':
alphabet[12]++;
break;
case 'N': case 'n':
alphabet[13]++;
break;
case 'O': case 'o':
alphabet[14]++;
break;
case 'P': case 'p':
alphabet[15]++;
break;
case 'Q': case 'q':
alphabet[16]++;
break;
case 'R': case 'r':
alphabet[17]++;
break;
case 'S': case 's':
alphabet[18]++;
break;
case 'T': case 't':
alphabet[19]++;
break;
case 'U': case 'u':
alphabet[20]++;
break;
case 'V': case 'v':
alphabet[21]++;
break;
case 'W': case 'w':
alphabet[22]++;
break;
case 'X': case 'x':
alphabet[23]++;
break;
case 'Y': case 'y':
alphabet[24]++;
break;
case 'Z': case 'z':
alphabet[25]++;
default: break;
}
}
}
for(int i = 0; i <= 25; i++){
printf("%c: \t%d\n", ('a' + i), alphabet[i]);;
}
}
int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength){
int sentenceLength;
int counter, wordSize = 0;
for(int i = 0; i < lineTotal; i++){
sentenceLength = strlen(&text[i][0]);
for(int j = 0; j < sentenceLength; j++){
if(text[i][j] == ' '){
if(counter == wordLength){
wordSize++;
counter = 0;
}
else{
counter = 0;
}
}
else{
counter++;
}
}
}
return wordSize;
}
void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
char maxWords[800];
char word[MAX_LINE_LENGTH], word2[MAX_WORD_LENGTH], *ptrText, *ptrTextCounter;
int counter, textCounter = 0;
int sentenceLength, wordTracker;
int lineFlag;
for(int i = 0; i < lineTotal; i++){
ptrText = &text[i][0];
sentenceLength = strlen(ptrText);
counter = 0;
for (int j = 0; j < sentenceLength + 1; j++){
wordTracker = 1;
if (text[i][j] == ' ' ){
if (counter != 0){
sprintf(word, "%.*s", counter, ptrText);
ptrTextCounter = &text[i][j+1];
lineFlag = j;
if(strstr(maxWords, word) == NULL){
for (int k = i; k < lineTotal; k++){
textCounter = 0;
if (lineFlag == j){
ptrTextCounter = &text[i][j+1];
}
else{
lineFlag = 0;
ptrTextCounter = &text[i][j+1];
}
for ( ; lineFlag < sentenceLength; lineFlag++){
if(text[k][lineFlag] == ' '){
if (textCounter != 0){
if(textCounter == counter){
sprintf(word2, "%.*s", textCounter, ptrTextCounter);
if(strcmp(word, word2) == 0){
wordTracker++;
}
}
ptrTextCounter = &text[k][lineFlag + 1];
textCounter = 0;
}
else{
ptrTextCounter = &text[k][lineFlag+1];
}
}
else{
textCounter++;
}
}
}
if(wordTracker == 1){
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
else{
printf("\n\"%.*s\"\t\tappeared %d times", counter, ptrText, wordTracker);
}
}
strcat(maxWords, word);
ptrText = &text[i][j+1];
counter = 0;
}
else{
ptrText = &text[i][j+1];
}
}
else{
counter++;
}
}
}
}
The problem is that you need to set counter to 0 at the start of every line.
for(int i = 0; i < lineTotal; i++){
sentenceLength = strlen(&text[i][0]);
counter = 0;
for(int j = 0; j < sentenceLength; j++){
You also need to check if the counter is equal at the end of each line.
for(int j = 0; j < sentenceLength; j++){
if(text[i][j] == ' '){
if(counter == wordLength){
wordSize++;
counter = 0;
}
else{
counter = 0;
}
}
else{
counter++;
}
}
if(counter == wordLength){
wordSize++;
counter = 0;
}
Hope this helps!

C Program not Receiving All Input

I am currently writing a program that is supposed to receive input from a text file and output statistics about the text such as the number of letters, size of words and how often they occur, and how many times each word occurs. However, every time I run the program, it does not read all the text. It only reads the first few words. Here is some sample text:
1
Hello my name is Bob
I live in Canada
It will only read "Hello my name is". It seems to cut off the last word. I import the text from a file using Input redirection from a text file in the compiler (I have to do it this way).
The number represents how many lines are supposed to be read. What should I do to correct my issue? I am very new to programming so I'm sure it is something basic.
#include <stdio.h>
#include <string.h>
#define MAX_LINE_LENGTH 80
#define MAX_WORD_LENGTH 20
#define MAX_LINES 10
void letterAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int wordLengthAnalysis(char [][MAX_LINE_LENGTH], int lineTotal, int wordLength);
void wordAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int main (void){
int lineTotal = 0;
int wordSize = 0;
char text[lineTotal][MAX_LINE_LENGTH];
char n[1] = {0};
fgets(n, 800, stdin);
lineTotal = n[0] - '0';
for(int i = 0; i < lineTotal; i++){}
fgets(text[i], MAX_WORD_LENGTH, stdin);
}
printf("\n***Letter count analysis***\n");
letterAnalysis(text, lineTotal);
printf("\n***Word length analysis***\n");
for (int i = 1; i <= MAX_WORD_LENGTH; i++){
wordSize = wordLengthAnalysis(text, lineTotal, i);
if (wordSize == 1){
printf("\n%-2d\tword of length %d", wordSize, i);
}
else{
printf("\n%-2d\twords of length %d", wordSize, i);
}
}
printf("\n\n***Word analysis***\n");
wordAnalysis(text, lineTotal);
return 0;
}
void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
int alphabet[26] = {0};
for (int i = 0; i < lineTotal; i++){
for(int j = 0; j < MAX_LINE_LENGTH; j++){
switch(text[i][j]){
case 'A': case 'a':
alphabet[0]++;
break;
case 'B': case 'b':
alphabet[1]++;
break;
case 'C': case 'c':
alphabet[2]++;
break;
case 'D': case 'd':
alphabet[3]++;
break;
case 'E': case 'e':
alphabet[4]++;
break;
case 'F': case 'f':
alphabet[5]++;
break;
case 'G': case 'g':
alphabet[6]++;
break;
case 'H': case 'h':
alphabet[7]++;
break;
case 'I': case 'i':
alphabet[8]++;
break;
case 'J': case 'j':
alphabet[9]++;
break;
case 'K': case 'k':
alphabet[10]++;
break;
case 'L': case 'l':
alphabet[11]++;
break;
case 'M': case 'm':
alphabet[12]++;
break;
case 'N': case 'n':
alphabet[13]++;
break;
case 'O': case 'o':
alphabet[14]++;
break;
case 'P': case 'p':
alphabet[15]++;
break;
case 'Q': case 'q':
alphabet[16]++;
break;
case 'R': case 'r':
alphabet[17]++;
break;
case 'S': case 's':
alphabet[18]++;
break;
case 'T': case 't':
alphabet[19]++;
break;
case 'U': case 'u':
alphabet[20]++;
break;
case 'V': case 'v':
alphabet[21]++;
break;
case 'W': case 'w':
alphabet[22]++;
break;
case 'X': case 'x':
alphabet[23]++;
break;
case 'Y': case 'y':
alphabet[24]++;
break;
case 'Z': case 'z':
alphabet[25]++;
default: break;
}
}
}
for(int i = 0; i <= 25; i++){
printf("%c: \t%d\n", ('a' + i), alphabet[i]);;
}
}
int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength){
int sentenceLength;
int counter, wordSize = 0;
for(int i = 0; i < lineTotal; i++){
sentenceLength = strlen(&text[i][0]);
for(int j = 0; j < sentenceLength + 2; j++){
if(text[i][j] == ' '){
if(counter == wordLength){
++wordSize;
counter = 0;
}
else{
counter = 0;
}
}
else{
counter++;
}
}
}
return wordSize;
}
void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
char maxWords[800];
char word[MAX_LINE_LENGTH], word2[MAX_WORD_LENGTH], *ptrText, *ptrTextCounter;
int counter, textCounter = 0;
int sentenceLength, wordTracker;
int lineFlag;
for(int i = 0; i < lineTotal; i++){
ptrText = &text[i][0];
sentenceLength = strlen(ptrText);
counter = 0;
for (int j = 0; j < sentenceLength + 1; j++){
wordTracker = 1;
if (text[i][j] == ' ' ){
if (counter != 0){
sprintf(word, "%.*s", counter, ptrText);
ptrTextCounter = &text[i][j+1];
lineFlag = j;
if(strstr(maxWords, word) == NULL){
for (int k = i; k < lineTotal; k++){
textCounter = 0;
if (lineFlag == j){
ptrTextCounter = &text[i][j+1];
}
else{
lineFlag = 0;
ptrTextCounter = &text[i][j+1];
}
for ( ; lineFlag < sentenceLength; lineFlag++){
if(text[k][lineFlag] == ' '){
if (textCounter != 0){
if(textCounter == counter){
sprintf(word2, "%.*s", textCounter, ptrTextCounter);
if(strcmp(word, word2) == 0){
wordTracker++;
}
}
ptrTextCounter = &text[k][lineFlag];
textCounter = 0;
}
else{
ptrTextCounter = &text[k][lineFlag+1];
}
}
else{
textCounter++;
}
}
}
if(wordTracker == 1){
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
else{
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
}
strcat(maxWords, word);
ptrText = &text[i][j+1];
counter = 0;
}
else{
ptrText = &text[i][j+1];
}
}
else{
counter++;
}
}
}
}
for(int i = 0; i < lineTotal; i++){}
fgets(text[i], MAX_WORD_LENGTH, stdin);
}
This should be MAX_LINE_LENGTH.

How does falling through cases in c work?

#include <stdio.h>
main() /* count digits, white space, others */
{
int c, i, nwhite, nother, ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; i++)
ndigit[i] = 0;
while ((c = getchar()) != EOF) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ndigit[c-'0']++;
break;
case ' ':
case '\n':
case '\t':
nwhite++;
break;
default:
nother++;
break;
}
}
printf("digits =");
for (i = 0; i < 10; i++)
printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n",
nwhite, nother);
return 0;
}
Question 1 - How does these cases work if c = 0 then does the control go to directly to the statements and break or does it remember that c = 0 and continue falling through until the statements?
#include <stdio.h>
int main()
{
int i = 0;
for(i = 0; i < 20; i++)
{
switch(i)
{
case 0: i+=5;
case 1: i+=2;
case 5: i+=5;
default: i+= 4;
break;
}
printf("%d ", i);
}
return 0;
}
Question 2 - In a program like this why does 2 add up in case 1? Where the current value of i will be 5? Does the control ignore all the remaining/underling case constant expressions until it finds a break if one case is true?
the switch in c jumps to the case with the matching value and then executes all code from there until it finds a break or switch ends. son in 2nd example for value 0 all other cases are evaluated too. if you don't want this you need a break.

Using for loops to print specific "non-vowel, vowel, non-vowel" words

I have a task to print a list of words made up of "non-vowel, vowel, non-vowel", i.e bab, bac, bad, bad ... through to zuz.
I have managed to create a code which does the first two letters but gets lost on the last loop and prints only '}' - which seems strange to me. The code is below:
#include <stdio.h>
#include <string.h>
int check_vowel(char c);
int check_consonant(char c);
int main ()
{
char c, c2, c3;
int cnt;
for (cnt = 0; cnt <= c; cnt++)
{
for (c = 'a'; c <= 'z'; c++)
{
if (check_vowel(c) == 0)
{
for (c2 = 'a'; c2 <= 'z'; c2++)
{
if (check_consonant(c2) == 0)
{
for (c3 = 'a'; c3 <= 'z'; c3++);
{
if (check_vowel(c3) == 0)
{
cnt++;
printf("%d || %c%c%c\n", cnt, c, c2, c3);
}
}
}
}
}
}
}
printf("Total names = %d", cnt);
return 0;
}
int check_vowel(char c)
{
switch(c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return 1;
default:
return 0;
}
}
int check_consonant(char c)
{
switch(c)
{
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
return 1;
default:
return 0;
}
}
The outputs are along the lines of:
1 || ba}
2 || be}
etc
The first bug is in this line:
for (c3 = 'a'; c3 <= 'z'; c3++);
Because of the semicolon at the end of that line, the iteration body is "do nothing". The block of code after it (from { to }) is just treated as something to do after this loop. When you enter this block of code, c3 will always be {, because it's the first character after z (in most character encodings). The fix: remove the semicolon.
The second bug is in the choice of conditions. The condition check_vowel(c3) == 0 (what you wrote) is not equal to check_consonant(c3) == 1 (what you want). For instance, { is not a vowel, but that doesn't make it a consonant. The fix: make your conditions positive.
Why don't try to iterate only over the proper sets:
static const char cons[] = "bcdfghjklmnpqrstvwxyz";
static const size_t cons_sz = sizeof cons - 1;
static const char vowels[] = "aeiou";
static const size_t vowels_sz = sizeof vowels - 1;
for (i = 0; i < cons_sz; i++)
for (j = 0; j < vowels_sz; j++)
for (k = 0; k < cons_sz; k++)
printf("%c%c%c\n", cons[i], vowels[j], cons[k]);

Resources