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;
}
Related
I have experienced some problem with segmentation when I'm learning through C, my aim is to swap the tabs in the program with spaces:
I have used the get_line template and modified the code to suit the situation. Here is the whole coded solution:
#include <stdio.h>
#define MAXLINE 1000
char line[MAXLINE];
char detabline[MAXLINE];
int get_line(void);
int main(void){
int len;
int i;
int nt = 0;
extern char detabline[];
extern char line[];
while ((len = get_line()) > 0){
for (i = 0; i < len; ++i){
if (line[i] == '\t'){
printf("%s", " ");
}
else{
printf("%s", line[i]);
}
}
}
return 0;
}
int get_line(void){
int c, i, nt;
nt = 0;
extern char line[];
for (i = 0; i < (MAXLINE - 1) && (c = getchar()) != EOF && ((c != '\t') || (c != '\n')); ++i){
line[i] = c;
}
if (c == '\n'){
line[i] = c;
++i;
}
else if (c == '\t'){
++nt;
}
line[i] = '\0';
return i;
}
The problem is to locate which memory isn't allocated correctly. I may have some redundant code in the solution by the way.
regarding:
for (i = 0; i < (MAXLINE - 1) && (c = getchar()) != EOF && ((c != '\t') || (c != '\n')); ++i){
this expression:
(c != '\t')
will result in no tab character ever being in the line[] array.
this expression:
(c != '\n')
will result in no newline character sequence ever being in the line[] array.
then, due those expressions, the line[] array will not be updated (ever again) when a tab or a newline is encountered due to those expressions causing an early exit from the for() loop
The following proposed code:
cleanly compiles
performs the desired functionality
and now, the proposed code:
#include <stdio.h>
#define MAXLINE 1000
char line[MAXLINE];
int main(void)
{
int i = 0;
int ch;
while ( i< MAXLINE-1 && (ch = getchar()) != EOF && ch != '\n' )
{
if ( ch == '\t')
{
line[i] = ' ';
}
else
{
line[i] = (char)ch;
}
i++;
}
printf( "%s\n", line );
}
Post a comment if you want further details about the proposed code.
I wrote the following function and when I run it , it produces an infinite loop and I dont understand why.
This function creates a dynamic array of dynamic strings. Every such string starts with a letter given, or with a capital letter which is compatible to the letter given:
void wordsStartWithLetter(char letter, char *str,char***newstr,int *numOfWords)
{
int i=0, count=0;
char *word;
char *delimiter = " ";
while (str[i] != '\0')
{
if (str[i]==letter ||str[i]==(letter-32 )) //if it founds the letter at the begining of the word, than run till the space//
{
while (str[i] != ' ' && str[i] != '\0' )
i++; //counting the number of words beginng with the letter given//
count++;
}
else
{
while (str[i] != ' ' && str[i] != '\0' )
i++;
}
}
*newstr = (char**)malloc (sizeof(char*)*count);
*numOfWords=count;
i=0;
word = strtok(str, delimiter); //we use strtok to separate each word from the origin string//
while(word!=NULL)
{
if (word[0]==letter ||word[0]==letter-32)
{
(*newstr)[i]=word; //insert the compatible words into the new 2D-string//
i++;
}
word = strtok(NULL, delimiter);
}
}
I call that function the by the following way:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#define SIZE 50
void Ex();
void wordsStartWithLetter(char letter, char *str,char***newstr,int *numOfWords) ;
void main()
{
Ex();
}
void Ex()
{
char ch;
char str[SIZE];
char **newstr;
int numOfWords,i;
printf("please enter a string: ");
_flushall();
gets(str);
printf("plese enter a letter: " );
_flushall();
ch=_getche();
wordsStartWithLetter(ch, str,&newstr,&numOfWords);
("the words of the origin string which start which %c :\n",ch);
for(i=0;i<numOfWords;i++)
printf("%s\n",newstr[i]);
for (i=0;i<numOfWords; i++)
free(newstr[i]);
free(newstr);
}
Consider this input string "a b" and assume the letter is c.
When i is 0 you enter the code below because str[0]is a which doesn't match the letter:
else
{
while (str[i] != ' ' && str[i] != '\0' )
i++; // Increment i from 0 to 1
}
In the above block, you increment i to 1 and then leave the block because str[1] is ' '
In the next main loop, you will again hit this code block:
else
{
while (str[i] != ' ' && str[i] != '\0' )
i++; // No increment, i.e. i stays at 1
}
but you will not increment i (as str[1] is a space). In other words - i remains at 1 and you have an infinite loop.
Maybe you can fix it by this:
else
{
while (str[i] != ' ' && str[i] != '\0' )
i++; // No increment, i.e. i stays at 1
// Add this line to remove the spaces
while (str[i] == ' ') i++;
}
basically we are provided with the main function:
#include <stdio.h>
#include <string.h>
#include <strings.h>
#define STORAGE 255
{
int c;
char s[STORAGE];
for(;;) {
(void) printf("n=%d, s=[%s]\n", c = getword(s), s);
if (c == -1)break;
}}
we are not to change that
and we have to create the function getword() which should contain a loop that reads a characters,
store it in a array in the address provided one by one and it should stop for whitespace (tab, space, eof)
basically i have this:
int getword(char *w)
{
char str[255];
int i = 0;
int charCount = 0;
printf("enter your sentence:\n");
gets(str);
/*this was provided by the professor, but i'm not sure how to use it
while (( iochar - getchar()) !=EOF);
*/
for(i = 0; str[i] != '\0'; i++) //loop that checks tab and spaces
{
if(str[i] != ' ' && str[i] != '\t')
{
charCount++;
}
}
printf("your string: '%s' contains %d of letters\n", str, charCount);
return 0;}
right now the output of the program is:
enter your sentence:
hey stockoverflow
your string: 'hey stockoverflow' contains 16 of letters
n=0, s=[]
so i'm saving the string and counting it, but i'm not storing it where i should be.
it should display n=16, s=[hey stockoverflow]
actually it should display n=3, s=[hey]
any help would be appreciated
This may be what you are looking for:
for(i = 0; str[i] != '\0'; i++) //loop that checks tab and spaces
{
if(str[i] != ' ' && str[i] != '\t')
{
charCount++;
}
else
{
str[i] = '\0'; // Terminate str
break; // Break out of the for-loop
}
}
printf("your string: '%s' contains %d of letters\n", str, charCount);
strcpy(w, str); // Add this line to copy str into w (which is s from main)
return strlen(w); // Return the length of the result string
#include <stdlib.h>
#include <stdio.h>
int main()
{
unsigned long c;
unsigned long line;
unsigned long word;
char ch;
c = 0;
line = 0;
word = 0;
while((ch = getchar()) != EOF)
{
c ++;
if (ch == '\n')
{
line ++;
}
if (ch == ' ' || ch == '\n' || ch =='\'')
{
word ++;
}
}
printf( "%lu %lu %lu\n", c, word, line );
return 0;
}
My program works fine for the most part, but when I add extra spaces, it counts the spaces as extra words. So for example, How are you? is counted as 10 words, but I want it to count as 3 words instead. How could I modify my code to get it to work?
I found a way to count words and between them several spaces the program will count only the words and not the several spaces also as words
here is the code:
nbword is the number of words, c is the character typed and prvc is the previously typed character.
#include <stdio.h>
int main()
{
int nbword = 1;
char c, prvc = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
nbword++;
}
if(c == prvc && prvc == ' ')
nbword-;
if(c == '\n')
{
printf("%d\n", nbword);
nbword = 1:
}
prvc = c;
}
return 0:
}
This is one possible solution:
#include <stdlib.h>
#include <stdio.h>
int main()
{
unsigned long c;
unsigned long line;
unsigned long word;
char ch;
char lastch = -1;
c = 0;
line = 0;
word = 0;
while((ch = getchar()) != EOF)
{
c ++;
if (ch == '\n')
{
line ++;
}
if (ch == ' ' || ch == '\n' || ch =='\'')
{
if (!(lastch == ' ' && ch == ' '))
{
word ++;
}
}
lastch = ch;
}
printf( "%lu %lu %lu\n", c, word, line );
return 0;
}
Hope this helped, good luck!
I have been able to kind of get my transposition cipher to work a little bit. However, i am running into problems such as not being able to take in more than 5 characters in a text file. Currently my program is also not able to go to a new line when the encrypted text is outputted into a output file. I also am having trouble cycling my transposition cipher over and over again.
For example, if trans1.txt contained the text "JacksJacksJacks" all in one line it should print "csJakcsJakcsJak" all on the first line of the trans2.txt
Also the transposition cipher should reset every line. It should restart from position 2 then 4 then 0 etc... every time its a new line.
#include <stdio.h>
int c, j, i, k,p=0;
char transposition[]={2,4,0,1,3}, input[256];
int main(){
FILE *file1=fopen("trans1.txt", "r");
FILE *file2=fopen("trans2.txt", "w");
while(fgets(input,sizeof(input),file1)!=NULL){
for(i=0;i<5;i++){
k=transposition[i];
fprintf(file2,"%c",input[k]);
}
}
return 0;
}
#include <stdio.h>
int main(){
char transposition[]={2,4,0,1,3};
char input[256] = "JacksJacksJacks\n";
int len = sizeof(transposition);
char ch, temp[len];
int i, j, k;
j=i=0;
do {
for( ; '\0'!=(ch = input[i]) && ch != '\n';++i){
temp[j++] = ch;
if(j == len){
j=0;
++i;
break;
}
}
while(j!=0){
temp[j++] = '.';//pading if(i % len != 0)
if(j == len)
j = 0;
}
for(k=0;i && k<len;++k){
printf("%c", temp[transposition[k]]);
}
}while(ch != '\n' && ch != '\0');
printf("\n");
return 0;
}
another way for the same thing
i=0;
do {
for(j=0;j<len;++j){
ch = input[i];
if(ch != '\n' && ch != '\0'){
temp[j] = ch;
++i;
} else {
temp[j] = '.';
}
}
if(temp[0] != '.')
for(k=0;k<len;++k){
printf("%c", temp[transposition[k]]);
}
}while(ch != '\n' && ch != '\0');
printf("\n");
Some hints:
What happens after the for-loop processes 5 characters?
Your problem seems character oriented. Why not use getc()?
For extra credit:
What happens if, just for example, there were fewer than 5 characters on the 2nd line?