Reading a whole line before printing result - c

Ok firstly I'm a total amateur on programming and i wanted to try something. I want to make a C program which will read a line and then if the characters are accepted to print "ACCEPTED" or "REJECTED" if the characters are valid or not.
So I've used a while loop and some if-else if to add the viable characters. The viable characters are the letters of the alphabet ',' '.' '/' '[' ']'. The problem is that after i type the whole line, it prints ACCEPTED and REJECTED for every character on the line. How can i get the program to read the whole line first and then print the result?
#include <stdio.h>
int main(void) {
char c;
c=getchar();
while(c!=EOF) {
while (c!='\n') {
if (c>='a' && c<='z') {
printf("OK!\n");
}
else if(c==','|| c=='.' ||c=='/') {
printf("OK!\n");
}
else if(c==']'||c=='[') {
printf("OK!\n");
}
else {
printf("ERROR!\n");
}
c=getchar();
}
c=getchar();
}
}

Sorry, my original answer did not seem to relate to your question. Skim reading fail.
Thank you for posting the code, it helps a lot when it comes to answering your question correctly.
Ignoring style for now, I would change your code in this way to make it print OK only when you finish parsing the entire line and it is exactly what #ScottMermelstein said but with code.
#include <stdio.h>
int main(void) {
int c; // This needs to be an int otherwise you won't recognize EOF correctly
int is_ok;
c=getchar();
while(c!=EOF) {
is_ok = 1; // Let's assume all characters will be correct for each line.
while (c!='\n') { // So long as we are in this loop we are on a single line
if (c>='a' && c<='z') {
// Do nothing (leave for clarity for now)
}
else if(c==','|| c=='.' ||c=='/') {
// Do nothing (leave for clarity for now)
}
else if(c==']'||c=='[') {
// Do nothing (leave for clarity for now)
}
else {
is_ok = 0; // Set is_ok to false and get out of the loop
break;
}
c=getchar();
}
if (is_ok) // Only print our result after we finished processing the line.
{
printf("OK!\n");
} else
{
printf("ERROR!\n");
}
c=getchar();
}
return 0; // If you declare main to return int, you should return an int...
}
However, I would recommend modularizing your code a little more. This will come with time and practice but you can write things in a way that is much easier to understand if you hide things away in appropriately named functions.
#include <stdio.h>
int is_valid_char(int c)
{
return (isalpha(c) || c == ',' || c == '.' || c == '/' || c == '[' || c == ']');
}
int main(void) {
int c;
int is_valid_line;
c=getchar();
while(c!=EOF) {
is_valid_line = 1;
while (c!='\n') {
if (!is_valid_char(c)) {
is_valid_line = 0; // Set is_valid_line to false on first invalid char
break; // and get out of the loop
}
c=getchar();
}
if (is_valid_line) // Only print our result after we finished processing the line.
{
printf("OK!\n");
} else
{
printf("ERROR!\n");
}
c=getchar();
}
return 0;
}

You can use scanf and putting a space before the format specifier %c to ignore white-space.
char ch;
scanf(" %c", &ch);

This might be what you are looking for?
Read a line and process good/bad chars and print either OK or Error.
#include <stdio.h>
int main ( void )
{
char buff[1000];
char *p = buff ;
char c ;
int flgError= 0 ; // Assume no errors
gets( buff ) ;
printf("You entered '%s'\n", buff );
while ( *p ) // use pointer to scan through each char of line entered
{
c=*p++ ; // get char and point to next one
if ( // Your OK conditions
(c>='a' && c<='z')
|| (c>='A' && c<='Z') // probably want upper case letter to be OK
|| (c==','|| c=='.' ||c=='/')
|| (c==']'||c=='[')
|| (c=='\n' ) // assume linefeed OK
)
{
// nothing to do since these are OK
}
else
{
printf ("bad char=%c\n",c);
flgError = 1; // 1 or more bad chars
}
}
if ( flgError )
printf ( "Error\n" );
else
printf ( "OK\n" );
}

Related

Turning a word into *** symbols

So the task is to turn each word in the sentence starting with uppercase into "***".
`
for (i = 1; input[i] != '\0'; i++)
if(isupper(input[i])) input[i] = '***';
printf("\n Changed sentence is: %s", input);
`
This is a code I've written so far. It can change only one character but I don't know how to do it with he whole word.
I assume input is a properly allocated, null terminated C string.
You scan (within the loop) one character at a time; similarly you can change one character at a time.
So you need an additional variable where you store if the word parsed should be converted to a sequence of asterisks.
As you encounter a uppercase letter at the beginning of a word the variable is set to true.
As you encounter the end of the current word (a whitespace) you reset the variable to false.
Finally you change (or not) the current character accordingly.
See the comments in the code
// you need a variable to record if the current word
// should be converted to a sequence of '*'
bool toAsterisk = false;
// sentence scanning loop (one character at a time)
// note that index starts at 0 (not 1)
for (i = 0; input[i] != '\0'; i++)
{
// check if the current word should be converted to asterisks
if( isupper( input[i] ) && toAsterisk == false )
{
toAsterisk = true;
}
// check if you rwach the end of the current word
if( input[i] == ' ' )
{
toAsterisk = true;
}
// convert to asterisks?
if( toAsterisk )
{
input[ i ] = '*';
}
}
The following is a potential solution:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char input[] = "The Mississippi river is very Wide.";
printf("%s\n", input);
for(int i = 0; i < strlen(input); i++)
{
if((i != 0) && isupper(input[i]))
{
printf("*** ");
while(input[i] != ' ')
i++;
}
else
{
printf("%c", input[i]);
}
}
if(ispunct(input[strlen(input) - 1]))
printf("\b%c\n", input[strlen(input) - 1]);
else
printf("\n");
return 0;
}
Output
$ gcc main.c -o main.exe; ./main.exe
The Mississippi river is very Wide.
The *** river is very ***.
Read through the line.
If character is capitalized, enter while loop until you get a space or end of line and replacing characters with *.
Print the line.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char line[1024] = "This should Replace capitalized Words!";
int i = 0;
printf("line: %s\n", line);
for (i = 0; i < strlen(line); i++) {
if (isupper(line[i])) {
while (line[i] != ' ' && line[i] != '\0' && isalpha(line[i])) {
line[i] = '*';
i++;
}
}
}
printf("line: %s\n", line);
return 0;
}
Outputs
$ gcc -Wall -Werror test.c -o t
line: This should Replace capitalized Words!
line: **** should ******* capitalized *****!
Well, following the feedback seen in the comments, here is my version that doesn't depend on the input line length or memory available to the program. It implements a finite state automaton, three states, to detect first letter, next letters and nonword letters. Following a possible implementation:
#include <stdio.h>
#include <ctype.h>
#define IDLE (0)
#define FIRST (1)
#define NEXT (2)
int main()
{
int status = IDLE;
int c;
while ((c = getchar()) != EOF) {
if (isupper(c)) {
switch (status) {
case IDLE:
status = FIRST;
printf("***");
break;
case FIRST: case NEXT:
status = NEXT;
break;
} /* switch */
} else if (islower(c)) {
switch (status) {
case IDLE:
putchar(c);
break;
case FIRST: case NEXT:
status = NEXT;
} /* switch */
} else {
switch (status) {
case IDLE:
putchar(c);
break;
case FIRST: case NEXT:
putchar(c);
status = IDLE;
break;
} /* switch */
} /* if */
} /* while */
} /* main */
By changing one character to three (you change them to three stars) you change length of string. Try starting from there. [This issue may affect the way loop should work]

print each letter after '.' for example if I enter a..bcde..fg..h the program will print bfh

I'm new to C, I have been asked to make a program in C asking to print each letter after a '.' after a user has entered an input.
For example if the user enters a..bcd..e.f..gh the output should be befg
which is the exact example I have been given in class.
I assume this would need to use pointers but I am unsure how to deal with this question, here is what I have tried to do so far. I know it is not correct, please help me understand how to use pointers to deal with this question.
#include <stdio.h>
int main() {
char *c, count =0;
printf("enter some characters");
scanf("%s", &c);
while( c != EOF ) {
if (c != '.') {
count ++;
}
else; {
printf("%s", c);
}
}
}
The program can look the following way
#include <stdio.h>
#define N 100
int main( void )
{
char s[N];
const char DOT = '.';
printf( "Enter some characters: " );
fgets( s, N, stdin );
for ( char *p = s; *p; ++p )
{
if ( p[0] == DOT && p[1] != DOT ) putchar( p[1] );
}
putchar( '\n' );
}
Its output might look like
Enter some characters: a..bcd..e.f..gh
befg
Take into account that here any symbol after a dot (except the dot itself) is printed. You can add a check that there is a letter after a dot.
You don't really need pointers for this, or even an array. Basically it's a simple state engine: read each character, if '.' is encountered, set a flag so the next character is printed.
#include <stdio.h>
int main() {
int c, flag = 0;
while ((c = getchar()) != EOF) {
if (c == '.')
flag = 1;
else if (flag) {
putchar(c);
flag = 0;
}
}
return 0;
}
There are some errors in your code:
- char* c means a pointer to one or more characters.
But where does it point to?
- scanf reads a string up to an "white space". White space characters are the space itself, a newline, a tab character or an EOF. scanf expects a format string and a pointer to a place in memory where it places what it reads. In your case c points to an undefined place and will overwrite whatever there is in memory.
- why do you place a ";" after the else? The else clause will end with the ";". So your program will do the print every time.
It helps you a lot if you format your code in a more readable way and give the variable names that give hint what they are used for.
Another very important thing is to initialize every variable that you declare. Errors with uninitialized variables are sometimes very hard to find.
I would do it this way:
#include <stdio.h>
int main(int argc, char* argv[])
{
// I read every single character. The getchar function returns an int!
int c = 0;
// This marks the program state whether we must print the next character or not
bool printNext = false;
printf("enter some characters");
// We read characters until the buffer is empty (EOF is an integer -1)
do
{
// Read a single character
c = getchar();
if ( c == '.')
{
// After a point we change our state flag, so we know we have to print the next character
printNext = true;
}
else if( c != EOF )
{
// When the character is neither a point nor the EOF we check the state
if( printNext )
{
// print the character
printf( "%c", c );
// reset the state flag
printNext = false;
}
}
// read until the EOF occurs.
}
while( c != EOF );
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char letter;
char *c;
c = malloc(256);
printf("enter the string : ");
scanf("%s", c);
while( (letter=*(c)) != '\0' )
{
if (letter == '.')
{
c++;
letter=*c;
if(letter!='.')
printf("%c",letter);
else
{
while(letter=='.')
{
c++;
letter=*c;
}
printf("%c",letter);
}
}
c++;
}
printf("\n");
}

How to Accept Standard Input in C from the Linux Command Line

I am trying to accept a string from the standard input in Linux, take the given string and change the 'A'(s) and 'a'(s) to '#', and output the altered string.
In linux I am running this: echo "This problem is an EASY one" | ./a2at
My a2at.c program contains this:
#include <stdio.h>
#include <string.h>
int main(int argc, char *words[])
{
int i = 0;
char b[256];
while(words[i] != NULL)
{
b[i] = *words[i];
if(b[i] =='a' || b[i]=='A')
{
b[i] = '#';
}
printf("%c",b[i]);
}
return 0;
}
Any help would be really appreciated! I know that I am pretty far off from the right code.
You may use getchar() in order to read a single character at a time, or fgets() in order to read a complete line each time.
The easiest solution would be to use getch in a simple infinite loop:
while (1) {
int ch = getchar();
if (ch == EOF) {
break;
} else if (ch == 'a' || ch == 'A') {
putchar('#');
} else {
putchar(ch);
}
}
As #BLUEPIXY said in his comment, you could use getchar function from stdio.h, just do man getchar in your shell to have more details about the usages. This code could help you, but don't hesitate to use the man command :) !
#include <stdio.h>
int main(void)
{
int c;
while ((c=getchar()) && c!=EOF) {
if (c == 'a' || c== 'A')
c = '#';
write(1, &c, 1); // Or printf("%c", c);
}
return (0);
}

K&R answer 1-12 (using functions to reduce the number of lines of code)

I have written the following program to answer Kernighan and Ritchies ch1 problem 12.
The issue is that I have never really understood how to properly use functions and would like to know why the one I wrote into this program, getcharc(), does not work?
What are good resources that explain correct function usage. Where? and How?
I know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
#include <stdio.h>
int getcharc ();
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
getcharc(c);
}
while ( c == '\b') {
getcharc(c);
}
while ( c == '\\') {
getcharc(c);
}
while ( c == ' ') {
getcharc(c);
}
putchar(c);
}
}
int getcharc ()
{
int c;
c = getchar();
printf("\n");
return 0;
}
The original program (and I know it has bugs), without the function was:
#include <stdio.h>
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
c = getchar();
printf("\n");
}
while ( c == '\b') {
c = getchar();
printf("\n");
}
while ( c == '\\') {
c = getchar();
printf("\n");
}
while ( c == ' ') {
c = getchar();
printf("\n");
}
putchar(c);
}
}
So all I am trying to do with the function is to stop
c = getchar();
printf("\n");
being repeated every time.
What, exactly, is this getcharc() function supposed to do? What it does, is read a character from input, print a newline, and return zero. The character just read from input is discarded, because you didn't do anything with it. When it's called, the return value is ignored as well. In each of the places where it is called, you're calling it in an infinite loop, because there's no provision made for changing the loop control variable.
Perhaps you were intending something like c = getcharc(), but that wouldn't really help because you aren't returning c from the function, anyway. (Well, it would help with the "infinite loop" part, anyway.)
What's the point of this function anyway? If you just use getchar() correctly in its place, it looks like you'd have your solution, barring a few other bugs.
One of the possible solution is, change prototype for your function to int getcharc (int c, int flag).
Now your code after some modification;
#include <stdio.h>
int getcharc (int c, int flag);
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
int flag = 0; //to keep track of repeated newline chars.
while ((c = getchar()) != '\n') {
flag = getcharc(c, flag); // call getcharc() for each char in the input string. Testing for newline and printing of chars be done in the getcharc() function
}
return 0;
}
int getcharc (int c, int flag)
{
if( (c == ' ' || c == '\t' || c == '\b' || c== '\\') && flag == 0)
{
printf("\n");
flag = 1;
}
else
{
if(c != ' ' && c != '\t' && c != '\b' && c!= '\\')
{
putchar(c);
flag = 0;
}
}
return flag;
}
EDIT:
but I wanted to keep the nested while statements rather than using || or
Your nested while loop is executing only once for each character as grtchar() reads one character at one time. No need of nested loops here! You can check it by replacing while to if and your code will give the same output for a given string. See the output here.
know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
You make your program work to some extent (with your bugs) by adding an if condition and a break statement as;
#include <stdio.h>
int getcharc (int c);
int main()
{
int c;
while ((c = getchar()) != '\n') {
while ( c == '\t') {
c = getcharc(c);
if(c != '\t')
break;
}
....
....
while ( c == ' ') {
c = getcharc(c);
if(c != ' ')
break;
}
putchar(c);
}
return 0;
}
int getcharc (int c)
{
c = getchar();
printf("\n");
return c;
}
// compiled by my brain muhahaha
#include <stdio.h>
int getcharc(); // we prototype getcharc without an argument
int main()
{
int c; // we declare c
// read character from stdio, if end of file quit, store read character in c
while ((c = getchar()) != EOF) {
// if c is tab \t call function getcharc() until forever since c never changes
while ( c == '\t') {
getcharc(c); // we call function getcharc with an argument
// however getcharc doesn't take an argument according to the prototype
}
// if c is \b call function getcharc() until forever since c never changes
while ( c == '\b') {
getcharc(c);
}
// if c is \\ call function getcharc() until forever since c never changes
while ( c == '\\') {
getcharc(c);
}
// if c is ' ' call function getcharc() until forever since c never changes
while ( c == ' ') {
getcharc(c);
}
// since we never will get here but if we happened to get here by some
// strange influence of some rare cosmic phenomena print out c
putchar(c);
}
}
// getcharc doesn't take an argument
int getcharc ()
{
int c; // we declare another c
c = getchar(); // we read from the keyboard a character
printf("\n"); // we print a newline
return 0; // we return 0 which anyway will never be read by anyone
}
maybe you are getting confused with the old K&R
nowadays when you write a function argument you specify it like
int getcharch(int c)
{
...
}

C - Integer Input Validation Code

I have the following code in C:
#include "stdafx.h"
#include <stdlib.h>
#include <cstring>
#include <ctype.h>
int main()
{
char buffer[20];
int num;
bool valid = true;
printf("Please enter a number\n");
fgets(buffer, sizeof(buffer), stdin);
printf("\n\n");
if(!isdigit(buffer[0])) //Checking if the first character is -
{
if(buffer[0] != '-')
{
valid = false;
}
else
{
if(!isdigit(buffer[1]))
{
valid = false;
}
}
}
char *pend = strrchr(buffer, '\n'); //Replacing the newline character with '\0'
if (pend != NULL)
{
*pend = '\0';
}
for (int i = 1; i < strlen(buffer); i++) //Checking that each character of the string is numeric
{
if (!isdigit(buffer[i]))
{
valid = false;
break;
}
}
if(valid == false)
{
printf("Invalid input!");
}
else
{
num = atoi(buffer);
printf("The number entered is %d", num);
}
getchar();
}
Basically, the code ensures that the user input is a positive or negative whole number. No letters, floating point numbers etc. are allowed.
The code works perfectly and does its job well.
However, the code is too long and I have to implement it in a number of programs. Is there a simple way to perform all of the above in C? Maybe a shorter alternative that ensures that the input is:
i) not a letter
ii) a positive or negative WHOLE number
bool valid = false;
char *c = buffer;
if(*c == '-'){
++c;
}
do {
valid = true;
if(!isdigit(*c)){
valid = false;
break;
}
++c;
} while(*c != '\0' && *c != '\n');
Note: this will not handle hex values, but will pass octal (integers starting in 0)
I also have to agree that this should be placed in a common library and called as a function.
Although some people have pointed out that strtol may not give you the errors you need, this is a very common type of thing to do, and therefore it does exist in the standard library:
http://www.cplusplus.com/reference/cstdio/sscanf/
#include <stdio.h>
// ....
valid = sscanf (buffer,"%d",&num);
Another comment is that you should not be afraid of writing complicated and useful code, and modularizing it. Create a library for the input parsing routines you find useful!

Resources