#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!
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.
This program should replace two spaces with an x, using only getchar() and putchar(). My approach was to store the space in a buffer and then print it out. But the program replaces every space with an x. Can someone help me out?
#include <stdio.h>
#define MAX 2
char arr[MAX];
int ret = 0;
char second;
int main()
{
for(int i=0; ; )
{
if ( (ret = getchar())!= EOF)
{
putchar(ret);
}
if(ret==' '&&second==' ')
{
arr[i]=ret;
arr[i]='x';
putchar(arr[i]);
}
}
return 0;
}
When you read a character, first check if it's a space. If not, just print it. If it is read another character, then if the second is a space print an x otherwise print a space and the character you just read.
int c;
while ((c = getchar()) != EOF) {
if (c != ' ') {
putchar(c);
} else {
c = getchar();
if (c == EOF) {
putchar(' ');
} else if (c == ' ') {
putchar('x');
} else {
putchar(' ');
putchar(c);
}
}
}
I wrote this program that replaces two spaces with an '*'.
How do I modify the code so that it does the same thing regardless of the string size? Is it even possible only using putchar and getchar?
#include <stdio.h>
int c;
char buffer[256];
int counter= 0;
int i;
int main()
{
while ((c = getchar()) != '\n'&&c!=EOF) {
buffer[counter] =c;
counter++;
if (counter >=255) {
break;
}
}
for(i=0; i<256; i++) {
if(buffer[i]== ' '&&buffer[i+1]==' ')
{
buffer[i]= '*';
putchar(buffer[i]);
i = i + 2;
continue;
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
The problem statement doesn't require you to store the complete input in a buffer. The decision on what character to output only depends on the last two characters of input. Consider the following code:
#include <stdio.h>
int main(void)
{
// two variables for the last two input characters
int c = EOF, last = EOF;
while ((c = getchar()) != EOF)
{
// if both are a space, store a single '*' instead
if (c == ' ' && last == ' ')
{
c = '*';
last = EOF;
}
// print the output, and shift the buffer
if (last != EOF)
putchar(last);
last = c;
}
// take care of the last character in the buffer after we see EOF
if (last != EOF)
putchar(last);
}
no need for malloc and friends at all. This is a good expample for a problem that requires you to think carefully, before writing code, in order to not waste unnecessary resources on buffers.
Code for just printing:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char prev = EOF, curr;
while ((curr =(char)getchar()) != '\n' && curr != EOF)
{
if(curr==' '&&prev==' ')
{
curr = '*';
prev = EOF;
}
if (prev != EOF)
putchar(prev);
prev = curr;
}
putchar(prev);
return 0;
}
Using realloc for actually changing the string:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned int len_max = 128;
char *m = malloc(len_max);
char c;
int counter= 0;
int i;
int current_size = 256;
printf("please input a string\n");
while ((c = getchar()) != '\n' && c != EOF)
{
m[counter] =(char)c;
counter++;
if(counter == current_size)
{
current_size = i+len_max;
m = realloc(m, current_size);
}
}
for(i=0; i<counter; i++)
{
if(m[i]== ' '&&m[i+1]==' ')
{
m[i]= '*';
putchar(m[i]);
i = i + 2;
continue;
}
putchar(m[i]);
}
putchar('\n');
free(m);
m = NULL;
return 0;
}
I need to write program that get Input from user and in case i have quate (") i need to change all the chars inside the quotes to uppercase.
int main()
{
int quoteflag = 0;
int ch = 0;
int i = 0;
char str[127] = { '\0' };
while ((ch = getchar()) != EOF && !isdigit(ch))
{
++i;
if (ch == '"')
quoteflag = !quoteflag;
if (quoteflag == 0)
str[i] = tolower(ch);
else
{
strncat(str, &ch, 1);
while ((ch = getchar()) != '\"')
{
char c = toupper(ch);
strncat(str, &c, 1);
}
strncat(str, &ch, 1);
quoteflag = !quoteflag;
}
if (ch == '.')
{
strncat(str, &ch, 1);
addnewline(str);
addnewline(str);
}
else
{
if ((isupper(ch) && !quoteflag))
{
char c = tolower(ch);
strncat(str, &c, 1);
}
}
}
printf("\n-----------------------------");
printf("\nYour output:\n%s", str);
getchar();
return 1;
}
void addnewline(char *c)
{
char tmp[1] = { '\n' };
strncat(c, tmp, 1);
}
So my problem here is in case my input is "a" this print at the end "A instead of "A" and i dont know why
The problem is that you are using strncat in a weird way. First, strncat will always do nothing on big-endian systems. What strncat does is read the inputs ... as strings. So passing and int (four or eight bytes) into the function, it'll read the first byte. If the first byte is 0, then it'll believe it is the end of the string and will not add anything to str. On little endian systems, the first byte should be the char you want, but on big-endian systems it will be the upper byte (which for an int that holds a value less than 255, will always be zero). You can read more about endianness here.
I don't know why you're using strncat for appending a single character, though. You have the right idea with str[i] = tolower(ch). I changed int ch to char ch and then went through and replaced strncat(...) with str[i++] = ... in your code, and it compiled fine and returned the "A" output you wanted. The source code for that is below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int quoteflag = 0;
char ch = 0;
int i = 0;
char str[127] = { '\0' };
while ((ch = getchar()) != EOF && !isdigit(ch))
{
if (ch == '"')
quoteflag = !quoteflag;
if (quoteflag == 0)
str[i++] = tolower(ch);
else
{
str[i++] = ch;
while ((ch = getchar()) != '\"')
{
char c = toupper(ch);
str[i++] = c;
}
str[i++] = ch;
quoteflag = !quoteflag;
}
if (ch == '.')
{
str[i++] = '.';
str[i++] = '\n';
str[i++] = '\n';
}
else
{
if ((isupper(ch) && !quoteflag))
{
char c = tolower(ch);
str[i++] = c;
}
}
}
printf("\n-----------------------------");
printf("\nYour output:\n%s", str);
getchar();
return 1;
}
You should delete the ++i; line, then change:
str[i] = tolower(ch);
To:
str[i++] = tolower(ch);
Otherwise, since you pre-increment, if your first character is not a " but say a, your string will be \0a\0\0.... This leads us on to the next problem:
strncat(str, &ch, 1);
If the input is a", then strncat(str, &'"', 1); will give a result of \"\0\0... as strncat will see str as an empty string. Replace all occurrences with the above:
str[i++] = toupper(ch);
(The strncat() may also be technically undefined behaviour as you are passing in an malformed string, but that's one for the language lawyers)
This will keep track of the index, otherwise once out of the quote loop, your first str[i] = tolower(ch); will start overwriting everything in quotes.
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
int main()
{
unsigned long c;
unsigned long line;
unsigned long word;
char ch;
c = 0;
line = 0;
word = 0;
printf("Please enter text:\n");
while((ch = getchar()) != EOF)
{
c ++;
if (ch == '\n')
{
line ++;
}
if (ch == ' ' || ch == '\n')
{
word ++;
}
}
printf( "%lu %lu %lu\n", c, word, line );
return 0;
}
Right now my program works and it counts correctly for characters, words, and lines. But for words like That's, the program counts it as 1 word and I want it to count as 2 words. What would I need to add to account for that?
if(ch =='\'' || ch == ' ' || ch == '\n')
{
word++;
}