How to append a char into array and tokenize it C - c

In my main function I am using letter(ch). I am trying to get some letter characters to become a string or token. Before using the append function it would just print all the characters out.
//output
000: u
001: s
002: e
003: .
004: s
005: y
006: s
007: t
008: e
009: m
010: .
011: i
012: o
013: ;
I found an appending function that gets the letter characters into the array, but it prints out like a pyramid. How do I get the last result when it's done appending, and use the '\0' to split it? Shouldn't it have already split it by the initial '\0' in the append function? Am I approaching this in the right direction? Is there something I'm missing in order for the split after the null?
//output
000: u
001: us
002: use
003: .
004: uses
005: usesy
006: usesys
007: usesyst
008: usesyste
009: usesystem
010: .
011: usesystemi
012: usesystemio
013: ;
//main.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include "ch_type.h"
FILE *file;
char line[400];
int line_num;
char ch;
void append(char* line, char ch)
{
int length = strlen(line);
line[length] = ch;
line[length + 1] = '\0';
}
int main()
{
file = fopen("source.txt", "r");
while((ch = fgetc(file)) != EOF)
{
if(space(ch))
{
printf(" %03d: %c\n", line_num++, ch);
}
if(letter(ch))
{
append(line, ch);
printf(" %03d: %s\n", line_num++, line);
}
if(separator(ch))
{
printf(" %03d: %c\n", line_num++, ch);
}
}
return 0;
}
//ch_type.h
int space(int ch)
{
return ((ch == ' '));
}
int letter(int ch)
{
return (((ch >= 'a') && (ch <= 'z')) || (ch >= 'A') && (ch <= 'Z'));
}
int separator(int ch)
{
return ((ch == '#') || (ch == '(') || (ch == ')') || (ch == '{') || (ch == '}') || (ch == '[') || (ch == ']')
|| (ch == '<') || (ch == '>') || (ch == '.') || (ch == ',') || (ch == ':') || (ch == ';'));
}

Print line when you enter if(space(ch)) or if(separator(ch)) instead of after finding each character of a line. After that, set the first byte to 0 so the string is "empty" again:
if(space(ch))
{
printf(" %03d: %s\n", line_num++, line);
line[0] = '\0';
printf(" %03d: %c\n", line_num++, ch);
}
if(letter(ch))
{
append(line, ch);
}
if(separator(ch))
{
printf(" %03d: %s\n", line_num++, line);
line[0] = '\0';
printf(" %03d: %c\n", line_num++, ch);
}
You should probably also prepend else to both if(letter(ch)) and if(separator(ch)). This might improve performance a little since none of these conditions overlap.
Note that this is assuming that separators and spaces don't go together, but that shouldn't necessarily matter.
Here is a simplified version of this that doesn't require duplicated code:
if(letter(ch))
{
append(line, ch);
}
else
{
printf(" %03d: %s\n", line_num++, line);
line[0] = '\0';
}
if(space(ch) || separator(ch))
{
printf(" %03d: %c\n", line_num++, ch);
}

Related

Array based search function

I have been trying to create a search function based exclusively on arrays rather than strings. The problem that I currently seem to be finding is that the code is tagging locations, without actually finding the correct letters. The end goal is for the code to find the full word and state how many characters it is into the line. Any help would be greatly appreciated.
int main()
{
int read = 1, i = 0, z = 0, q, o = 0, b;
char a[15];
char letters [] = "HELLOMYNAMEISELDERPRICEANDIHAVECOMETOSHAREWITHYOUTHISMOSTAMAZINGBOOK";
printf("HELLOMYNAMEISELDERPRICEANDIHAVECOMETOSHAREWITHYOUTHISMOSTAMAZINGBOOK\n");
printf("Please type in a word to search for in upper case:\n");
scanf(" %c", &a[1]);
scanf("%c", &a[2]);
if (a[2] != '\n') {scanf("%c", &a[3]); q=2;}
if (read == 1) {if (a[3] != '\n') {scanf("%c", &a[4]); q=3;} else read = 0;}
if (read == 1) {if (a[4] != '\n') {scanf("%c", &a[5]); q=4;} else read = 0;}
if (read == 1) {if (a[5] != '\n') {scanf("%c", &a[6]); q=5;} else read = 0;}
if (read == 1) {if (a[6] != '\n') {scanf("%c", &a[7]); q=6;} else read = 0;}
if (read == 1) {if (a[7] != '\n') {scanf("%c", &a[8]); q=7;} else read = 0;}
if (read == 1) {if (a[8] != '\n') {scanf("%c", &a[9]); q=8;} else read = 0;}
if (read == 1) {if (a[9] != '\n') {scanf("%c", &a[10]); q=9;} else read = 0;}
if (read == 1) {if (a[10] != '\n') {scanf("%c", &a[11]); q=10;} else read = 0;}
if (read == 1) {if (a[11] != '\n') {scanf("%c", &a[12]); q=11;} else read = 0;}
if (read == 1) {if (a[12] != '\n') {scanf("%c", &a[13]); q=12;} else read = 0;}
if (read == 1) {if (a[13] != '\n') {scanf("%c", &a[14]); q=13;} else read = 0;}
if (read == 1) {if (a[14] != '\n') {scanf("%c", &a[15]); q=14;} else read = 0;}
while (i != 1){
printf("line read\n");
if (a[1] == letters[z]){
printf("Found");
for (int p=0; p < q; p++){
o = z+p;
printf("checking for word\n");
if (a[p] == letters[o]){
printf("That bitch");}
else {break;}
}}
z++;
if (letters[z]=='\n'){i = 1;}
}
printf("%c", letters[z]);
printf("hmmm");
}
This redefined code should work for you:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "HELLOMYNAMEISELDERPRICEANDIHAVECOMETOSHAREWITHYOUTHISMOSTAMAZINGBOOK";
char letter[100];
int i, j, k, counter;
i = j = k = counter = 0;
printf("%s\n", str);
printf("Enter a substring to find: ");
scanf("%s", letter);
for (i = 0; str[i]; i++) { // str[i] != '\0'
if (str[i] == letter[j]) {
for (k = i, j = 0; str[k] && letter[j]; j++, k++)
if (str[k] != letter[j])
break;
if (!letter[j]) { // when letter[j] meets false and substring found
printf("\nFound at %d!\n", counter);
return 0;
}
} else {
printf("."); // for decoration
counter++;
}
}
printf(" No matches!\n");
return 0;
}
Sample Output
HELLOMYNAMEISELDERPRICEANDIHAVECOMETOSHAREWITHYOUTHISMOSTAMAZINGBOOK
Enter a substring to find: BOOK
................................................................
Found at 64!

Count how many times a word is used. C

I am trying to count the number of loops and emptylines in a string entered by a user. So here is the way I did it:
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
int main(void) {
int i, lines, loopF = 0, loopW = 0, loopDW = 0, empty = 0;
char *p, str[200];
const char test[10] = "while";
char *f;
printf("Enter a string. Ctrl+Z for exit.\n");
while (fgets(str, 200, stdin) != NULL) {
if (f = strstr(str, test)) { //first way
loopW++;
}
for (i = 0; i < strlen(str); i++) {
// count loops
if (str[i] == 'f' && str[i + 1] == 'o' && str[i + 2] == 'r') {
loopF++;
}
if (str[i] == 'w' && str[i + 1] == 'h' && str[i + 2] == 'i'
&& str[i + 3] == 'l' && str[i + 4] == 'e') { // second way
loopW++;
}
if (str[i] == 'd' && str[i + 1] == 'o') {
loopDW++;
if (loopDW >= 1)
loopW--;
}
}
// count empty lines
p = str;
lines = 0;
while (*p != '\n') {
if (*p != ' ') {
lines = 1;
}
p++;
}
if (!lines) {
empty++;
lines = 0;
}
}
printf("---------------------\n");
printf(" Empty lines: %d \n\n", empty);
printf(" Number of loops:\n");
printf(" For: %d \n", loopF);
printf(" While: %d \n", loopW);
printf(" Do/While: %d \n", loopDW);
printf("---------------------\n");
return 0;
}
I did it for 2 ways only for "while" to test but when a user types "whilethis" or "thiswhile" it counts it(which is not what I want). I want when there is only a while(a loop) to be counted and not with other symbols but i have no idea how to do it. Same is for do/while and for loops. Any help here? :)
The proper solution also needs to handle strings and comments
print("I have no for() loops")
/* commented out for() loop */
char* c = "for()\"loop\\";
If you do not care about this, and really want to use plain C, I would recommend "strtok" function which splits string into the words using delimiters (which would be basically all non-alphanumeric symbols in your case -- space, brackets, comma, etc...). Then once you have words, you can just strcmp() them with "do", "while" or "for"

What's wrong with my word count program?

Trying to make a function that outputs the count of words a user enters into the program. I keep getting a value of 2 with this code and I am not sure why or where I am going wrong. If someone can point me in the right direction that would be great. Thanks!
Here is the code:
#include <stdio.h>
#include <string.h>
int wordcount(char string[101]){
int i, words = 0;
for(i=0;string[i] != '\0';i++)
{
if(string[i] != '\t' && string[i] != '\0'){
words++;
while(string[i] != ' ' && string[i] != '\t' && string[i] !=
'\0')
i++;
}
}
return words;
}
int main (void) {
char input[101];
printf("Word Counter\n");
printf("============\n");
printf("string to be analyzed: \n");
scanf("%100[^\n]", input);
wordcount(input);
printf(" %s - words = %i\n", input, wordcount(input));
}
The main problem now is there are two.
if(string[i] != '\t' && string[i] != '\0'){ deterioration, changing for the worse
i is +1 to twice in the for and while.
For example, it will change as follows.
int wordcount(char string[101]){
int i, words = 0;
for(i=0;string[i] != '\0'; i++){
if(string[i] != ' ' && string[i] != '\t'){// assuming not included the newline.
words++;
i += strcspn(&string[i], " \t") -1;// i point to last character of word
}
}
return words;
}
or i changes it will be in one place.
int wordcount(char string[]){
int i, words = 0;
char prev =' ';
for(i=0;string[i] != '\0'; i++){
if(isspace(prev) && !isspace(string[i])){//isspace in <ctype.h>
words++;//count front edge
}
prev = string[i];
}
return words;
}

InfixToPostfix code C

I code this in C, it's for infix to postfix translation, but It doesn't work and I can't understand why, I changed it many times...
The input should be a (supposed correct) expression between parenthesis in infix notation, the usual way we write with * and / having precedence on + and -, and the parenthesis giving precedence.
The postfix notation doesn't have parenthesis, for example:
If I put an input expression like((8-9)/6)
the expected output is 8 9 - 6 /
The program starts, but the output is really wrong, for example:
input: ((8-9)+7) output: 8-97 expected output: 8 9 7 - +
input: ((6+9)/7) output: 6+++++97 expected output: 6 9 + 7 /
here how I planned to do it:
1) If an operand is encountered, output it.
2) If a ( is encountered push it onto the Stack.
3) If an operator is encountered, then
Repeatedly pop from stack and output each operator which has same precedence as or higher precedence than the operator encountered.
Push the operator on the stack.
4) If a ) is encountered, then
Repeatedly pop from the stack and output each operator until a left parenthesis is encountered.
Remove the ) parenthesis.
#include <stdio.h>
#include <stdlib.h>
#define N 100
char ch;
struct stack {
char exp[N];
int index;
} stack;
void push (char ch) {
stack.exp[stack.index] = ch;
stack.index++;
}
char pop () {
stack.index--;
return stack.exp[stack.index];
}
int pr_op(char ch) {
if (ch == '+' || ch == '-')
return 0;
else if (ch == '*' || ch == '/')
return 1;
}
char translator(char ch) {
int i;
if (ch == '(')
{
push(ch);
}
else if (ch == ')')
{
i = stack.index;
while(stack.exp[--i] != '\0' && stack.exp[--i] != '(')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
putchar(ch);
}
else
{
pop();
}
}
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
i= stack.index;
while(stack.exp[--i] != '\0' && pr_op(stack.exp[i])>=pr_op(ch))
{
putchar(ch);
}
push(ch);
}
else //operand
{
putchar(ch);
}
}
main(int argc, char *argv[])
{
ch = getchar();
stack.index = 0;
while ( ch != '\0'){
stack.exp[stack.index]=ch;
translator(ch);
stack.index++;
ch = getchar();
}
printf("\n");
return 0;
}
These lines are incorrect
char transl() {
int i;
if (ch = '(') // <--- this line
{
push(ch);
}
else if (ch = ')') // <--- this line
{
...
Since you are assigning values to ch at the same time as testing it. It should be == not = like this
char transl() {
int i;
if (ch == '(')
{
push(ch);
}
else if (ch == ')')
{
...
Your code has many minor mistake. So, here you go. But I don't undestand what the result you expect
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
char ch;
struct stack {
char exp[N];
int index;
} stack;
void push (char ch) {
stack.exp[stack.index] = ch;
stack.index++;
}
char pop () {
stack.index--;
return stack.exp[stack.index];
}
int pr_op(char ch) {
if (ch == '+' || ch == '-')
return 0;
else if (ch == '*' || ch == '/')
return 1;
}
char translator(char ch) {
int i;
if (ch == '(')
{
push(ch);
}
else if (ch == ')')
{
i = stack.index;
while(stack.exp[--i] != '\0' && stack.exp[--i] != '(')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
putchar(ch);
}
else
{
pop();
}
}
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
i= stack.index;
while(stack.exp[--i] != '\0' && pr_op(stack.exp[i])>=pr_op(ch))
{
putchar(ch);
}
push(ch);
}
else //operand
{
putchar(ch);
}
}
main(int argc, char *argv[])
{
ch = getchar();
stack.index = 0;
while ( ch != '\0'){
stack.exp[stack.index]=ch;
translator(ch);
stack.index++;
ch = getchar();
}
printf("\n");
return 0;
}

Counting the vowels and characters in each word of a sentence

I have been trying to figure out how to count the vowels and characters in each word of a sentance.
For example
In hello there sentence
hello : 5 characters, 2 vowels
there : 5 characters, 2 vowels. I have seen the code for doing the same thing for a full sentence. But not word by word.
Below is the coding I've been working on
int main() {
char str[512] = "hello there", word[256];
int i = 0, j = 0, v, h;
str[strlen(str)] = '\0';
/* checking whether the input string is NULL */
if (str[0] == '\0') {
printf("Input string is NULL\n");
return 0;
}
/* printing words in the given string */
while (str[i] != '\0') {
/* ' ' is the separator to split words */
if (str[i] == ' ')
{
for (h = 0; word[h] != '\0'; ++h)
{
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')++v;
}
printf("\nVowels: %d", v);
word[j] = '\0';
printf("%s\n", word);
j = 0;
}
else
{
word[j++] = str[i];
}
i++;
}
word[j] = '\0';
/* printing last word in the input string */
printf("%s\n", word);
return 0;
}
The input will be all lower case. I'm having a hard time figuring this out.
While running the code I'm not getting the vowels count. I'm able to split the sentence. But vowel counting is not happening.
One fairly simple approach:
#include <stdio.h>
const char* s(int n)
{
return n == 1? "" : "s";
}
void count (const char* str)
{
for (int i = 0;;)
for (int v = 0, w = i;;)
{
int len;
char c = str[i++];
switch (c)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
v++;
default:
continue;
case ' ': case '\t': case '\n': case '\0':
len = i - 1 - w;
printf("'%.*s': %d character%s, %d vowel%s\n", len, str+w, len, s(len), v, s(v));
if (c)
break;
else
return;
}
break;
}
}
int main(void)
{
count("My words with vowels");
return 0;
}
This sounds an awful lot like a homework assignment..
here's some pseudo-code <-- below will NOT run as is. Just to show logic.
int c = 0;
int v = 0;
for (int i = 0; i < lengthOfSentence; i++){
if (stringName[i] == '\0') { //optionally '\n' may be more suitable
return;
}
if (stringName[i] == ' '){
print previousWord // + c, v in whatever format you want
c = 0;
v = 0;
}
if (stringName[i] == vowel) { //you can do this part like in your code
word[v+c] = stringName[i]; //get current char and add to next slot
v++;
}
else {
word[v+c] = stringName[i];
c++;
}
beyond that it's minute details like realizing v+c will give you total word length when printing, etc..
Try this code. it might help you
#include<stdio.h>
int main() {
char str[512] = "hello there", word[256];
int i = 0, j = 0, v=0,h; // you didn't initialize v to 0
str[strlen(str)] = '\0';
/* checking whether the input string is NULL */
if (str[0] == '\0') {
printf("Input string is NULL\n");
return 0;
}
/* printing words in the given string */
while (str[i] != '\0') {
/* ' ' is the separator to split words */
if (str[i] == ' ' ) {
for (h = 0; word[h] != '\0'; h++) {
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')
v++;
}
printf("%s :", word);
printf(" %d chracters,",strlen(word));
printf(" %d Vowels.\n", v);
j = 0; v=0;
word[j] = '\0';
} else {
word[j++] = str[i];
word[j] = '\0';
}
i++;
}
/* calculating vowels in the last word*/ // when NULL occurs, Wont enter into while loop.
for (h = 0; word[h] != '\0'; h++) {
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')
v++;
}
printf("%s :", word);
printf(" %d chracters,",strlen(word));
printf(" %d Vowels.\n", v);
return 0;
}
What you can probably do is, you can print the count for the characters and vowels when you encounter a " "(space) and then reset the counters. That way, you can find the characters and vowels for each word of the sentence.
If you understand the logic for doing this throughout a sentence, then you can also do it in single words by simple breaking the sentence into individual word and applying the same logic to each word. You can use the fact that words are separated by a space (or multiple, maybe) to break down the sentence into words.

Resources