Input string of unknown length - 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;
}

Related

Write a program to break long input lines into two or more shorter lines of length at most n

I am currently learning C and working on a problem that breaks input lines into lengths of n. Below is my current code where n is set to 30. When it reaches the n-th index it replaces that index with ' ' and then line breaks, but it will only do it for the first n characters and I'm unsure what isn't getting rest in order to it to continue making a new line at the nth index.
int getline2(void);
int c, len, cut, counter;
char line[MAXLINE];
main() {
while ((len = getline2()) > 0) {
if (len > BREAK) {
c = 0;
counter = 0;
while (c < len) {
if (line[c] == ' ') {
counter = c;
}
if (counter == BREAK) {
line[counter] = '\n';
counter = 0;
}
counter++;
c++;
}
}
printf("%s", line);
}
return 0;
}
int getline2(void) {
int c, i;
extern char line[];
for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c; //i gets incremented at the end of the loop
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
Your code is a little too complicated:
you do not need to store the bytes read from the file into an array, just output them one at a time, keeping track of the line length
when the line would become too long, output a newline and reset the count before you output the byte.
also not that none of these global variables deserves to be global.
and the prototype for main should be either int main(), int main(void) or int main(int argc, char *argv[]) or equivalent. main()` is an obsolete syntax that should be avoided.
Here is a modified version:
#include <stdio.h>
#define BREAK 30
int main() {
int c;
int len = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
putchar(c);
len = 0;
} else {
if (len >= BREAK) {
putchar('\n');
len = 0;
}
putchar(c);
len++;
}
}
return 0;
}

Replacing three 'a' in with a single '*' in a string

So my program should get input from an user and store it in an array. After that if the input string includes three 'a's in a row it should be replaced with a single '*'. However I can't seem to get it right. It only replaces the first a with a *. I tried to replace the following 2 a with a blank but the output looks funny.
For this exercise I have to use putchar() and getchar().
Thank you in advance.
#include <stdio.h>
char c;
char buffer[256];
int counter= 0;
int i;
int main()
{
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >255) {
break;
}
}
for(i=0; i<256; i++) {
if(buffer[i]== 'a'&&buffer[i+1]=='a'&&buffer[i+2]=='a')
{
buffer[i]= '*';
buffer[i+1]=' ';
buffer[i+2]=' ';
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
So my program should get input from an user and store it in an array.
After that if the input string includes three 'a's in a row it should
be replaced with a single '*'. However I can't seem to get it right.
You almost got it! Just move index by 2 to and continue.
#include <stdio.h>
char c;
char buffer[256];
int counter= 0;
int i;
int main(void)
{
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >= 255) {
break;
}
}
buffer[counter] ='\0';
for(i=0; i<256; i++) {
if(buffer[i]== 'a'&&buffer[i+1]=='a'&&buffer[i+2]=='a')
{
buffer[i]= '*';
putchar(buffer[i]);
i = i + 2;
continue;
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
Test:
123aaa456aaa78
123*456*78
In string you must assign a end of character at the end and that is call null character \0 or just a numeric 0. Correct your code like below:-
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >=255) {
break;
}
}
buffer[counter] ='\0';// or buffer[counter] =0;
To avoid side effect in a string array always set all its value with 0 first:-
char buffer[256];
memset(buffer, 0, sizeof(buffer));
If you want to change the number of characters, you will need to create a different buffer to copy the output to.
If you really just want to output to the console, you could just write every character until you hit your matching string.
#include <stdio.h>
char c;
char buffer[256];
char output[256];
int counter= 0;
int i, j;
int main()
{
while ((c = getchar()) != '\n') {
buffer[counter] = c;
counter++;
if (counter >255) {
break;
}
}
buffer[counter] = 0;
for(i=0, j=0; i<256; i++, j++) {
if(buffer[i] == 'a' && buffer[i+1] == 'a'&& buffer[i+2] == 'a')
{
output[j]= '*';
i += 2;
}
else
output[j] = buffer[i];
putchar(output[j]);
}
putchar('\n');
return 0;
}
There are multiple problems in your code:
there is no reason to make all these variables global. Declare them locally in the body of the main function.
use int for the type of c as the return value of getchar() does not fit in a char.
you do not check for EOF.
your test for buffer overflow is off by one.
you do not null terminate the string in buffer. You probably make buffer global so it is initialized to all bits 0, but a better solution is to set the null terminator explicitly after the reading loop.
to replace a sequence of 3 characters with a single one, you need to copy the rest of the string.
You can use a simple method referred as the 2 finger approach: you use 2 different index variables into the same array, one for reading, one for writing.
Here is how it works:
#include <stdio.h>
int main() {
char buffer[256];
int c;
size_t i, j, counter;
for (counter = 0; counter < sizeof(buffer) - 1; counter++) {
if ((c = getchar()) == EOF || c == '\n')
break;
buffer[counter] = c;
}
buffer[counter] = '\0';
for (i = j = 0; i < counter; i++, j++) {
if (buffer[i] == 'a' && buffer[i + 1] == 'a' && buffer[i + 2] == 'a') {
buffer[j] = '*';
i += 2;
} else {
buffer[j] = buffer[i];
}
}
buffer[j] = '\0'; /* set the null terminator, the string may be shorter */
printf("modified string: %s\n", buffer);
return 0;
}

C, getc/fgetc - terminal null

I'm writing program that counts words in C, I know I can do this simply with fscanf. But I'm using getc.
I have file like this:
One two three four five.
I'm reading chars in while loop and breaking point is when I reach terminal null.
Will c = fgetc(input); or c = getc(input); set c = '\0'; after One_ and after two_ etc.?
When a return value of a function like getc() is EOF which is -1,then you have reached the end of file.try this code to count words:
#include <stdio.h>
int WordCount(FILE *file);
int main(void)
{
FILE *file;
if(fopen_s(&file,"file.txt","r")) {
return 1;
}
int n = WordCount(file);
printf("number of words is %d\n", n);
fclose(file);
return 0;
}
int WordCount(FILE *file)
{
bool init = 0;
int count = 0, c;
while((c = getc(file)) != EOF)
{
if(c != ' ' && c != '\n' && c != '\t') {
init = 1;
}
else {
if(init) {
count++;
init = 0;
}
}
}
if(init)
return (count + 1);
else
return count;
}

Manually counting the number of character in a string in C

I tried to manually count the number of characters in my string including any blank spaces. I coded this:
#include <stdio.h>
#include <stdlib.h>
void Unos(char* string, int duzina)
{
int i=0;
char c;
do {
c=getchar();
string[i]=c;
i++;
} while(c != '\n' && i<duzina);
}
int brojznak(char* str)
{
int i=0,br=0;
while(*str++ != '\0')
{
br++;
}
return br;
}
int main()
{
char recenica[100];
printf("Unesite recenicu\n");
Unos(recenica,100);
int i=0;
printf("%d",brojznak(recenica));
return 0;
}
This code doesn't work correctly, but I think it should. On the other hand, if we change condition:
int brojznak(char* str)
{
int i=0,br=0;
while(*str++ != '\0')
{
br++;
}
return br;
}
It again sometimes prints some random characters, but counts it accurately. Can anyone tell me what is wrong in this code?
String termination missing in Unos().
while(*str++ != '\0') in brojznak() does not know when to stop.
void Unos(char* string, int duzina) {
int i=0;
char c;
do {
c = getchar();
string[i] = c;
i++;
} while(c != '\n' && (i + 1) <duzina); // Insure enough room
string[i]='\0'; // add this
}
Some other refinements:
void Unos2(char* string, size_t duzina) {
size_t i = 0;
while ((i+1) < duzina) { Only attempt to read if space allows it.
int c = getchar(); // Use int to distinguish EOF from characters
if (c == EOF) break;
string[i] = c;
i++;
if (c == '\n') break;
}
string[i] = '\0'; // add this
}
try this
for(i=0; getchar()!='\n'; ++i)
;

Not counting spaces as words in c

#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!

Resources