Check if file has only alphanum characters in C - c

Run command sequence:
gcc -Wall main.c -o a.out
./a.out < inputfile.txt
I want to read from file like ./a.out < inputfile.txt and after iterating char by char, print OK if all the characters are alphanumeric or ERROR otherwise. I can't seem to get this to work.
inputfile.txt
the brown fox jumped over the dog
this is another string
here is another string
main.c
int main() {
char c;
while (!feof(stdin)) {
c = getchar();
if (!isalnum(c)) {
printf("ERROR!\n");
exit(1);
}
}
printf("OK\n);
return 0;
}

As the others said - spaces and new lines are not alnum characters. Use isalnum() + isspace() in this case. In addition to that consider using some kind of a flag instead of using exit() function:
#include <stdio.h>
#include <ctype.h>
int main()
{
int c;
char ok='Y';
while(c = getchar())
{
if(c == EOF) break;
if(!isalnum(c) && !isspace(c))
{
ok = 'N';
break;
}
}
printf("%c\n", ok);
return 0;
}
RTFM: http://www.cplusplus.com/reference/cctype/
I swear this is the last time when I'm gonna help out people who can't even debug their codes.

A space is not an alphanumeric character.
See the table in this page for what is or isn't "isalnum".

You're using feof wrong. feof returns true when the EOF indicator has already been set, i.e: when you have already read an EOF. So when stdin reaches end-of-file you still get one loop iteration with EOF, which isn't an alpha-numeric character. In order to make sure you can properly distinguish EOF from any valid character you should declare c as an int. I suggest:
int c = getchar();
while(c != EOF){
if(!isalnum(c)){
printf("ERROR!\n");
exit(1);
}
c = getchar();
}
printf("OK\n");

Related

Printing char of a file with fgetc() ending with a "?" symbol

I'm trying to print the chars (with fgetc) in a file one by a one with a while loop.
I'm using the latest Atom editor to write the code, and I compile with the GPP Compiler, by pressing F5 and the output is displayed in the xterm terminal.
int main(int argc, char const *argv[])
{
FILE* file = NULL;
file = fopen("text.txt", "r+");
int letter = 0;
if (file != NULL)
{
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
I expected the output to be the text in my file, which it is, but at the end there's a question mark symbol.
What I understood after doing some research is that my fgetc function reads the EOF like a normal character and prints it, resulting in a question mark symbol at the end.
Thanks for your help !
... ending with a “?” symbol
doing
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
you print letter before to check if it is EOF, so you (try to) print EOF which is not a character, producing the unexpected output
Example of a valid code :
while ((letter = fgetc(file)) != EOF)
putchar(letter); /* or printf("%c", letter); if you prefer */
I have been having the same issue and I found out that the return type for fgetc is an integer and it may be returning -1.

Reading text file from stdin stops at last line

I wrote a short program to test reading text files from stdin:
int main(){
char c;
while(!feof(stdin)){
c = getchar(); //on last iteration, this returns '\n'
if(!isspace(c)) //so this is false
putchar(c);
//remove spaces
while (!feof(stdin) && isspace(c)){ //and this is true
c = getchar(); // <-- stops here after last \n
if(!isspace(c)){
ungetc(c, stdin);
putchar('\n');
}
}
}
return 0;
}
I then pass it a small text file:
jimmy 8
phil 6
joey 7
with the last line (joey 7) terminated with a \n character.
My problem is, after it reads and prints the last line, then loops back to check for more input, there are no more characters to read and it just stops at the line noted in the code block.
Question: The only way for feof() to return true is after a failed read as noted here: Detecting EOF in C. Why isn't the final call to getchar triggering EOF and how can I better handle this event?
There are multiple problems in your code:
You do not include <stdio.h>, nor <ctype.h>, or at least you did not post the whole source code.
You use feof() to check for end of file. This is almost never the right method, as underscored in Why is “while ( !feof (file) )” always wrong?
You read the byte from the stream in a char variable. This prevents proper testing for EOF and also causes undefined behavior for isspace(c). Change the type to int.
Here is an improved version:
#include <stdio.h>
int main(void) {
int c;
while ((c = getchar()) != EOF) {
if (!isspace(c)) {
putchar(c);
} else {
//remove spaces
while ((c = getchar()) != EOF && isspace(c)) {
continue; // just ignore extra spaces
}
putchar('\n');
if (c == EOF)
break;
ungetc(c, stdin);
}
}
return 0;
}
While your method with ungetc() is functionally correct, it would be better to use an auxiliary variable this way:
#include <stdio.h>
#include <ctype.h>
int main(void) {
int c, last;
for (last = '\n'; ((c = getchar()) != EOF; last = c) {
if (!isspace(c)) {
putchar(c);
} else
if (!isspace(last))
putchar('\n');
}
}
return 0;
}

ch2=getchar() doesn't work after last input loop while((ch=getchar())!=EOF)

#include <stdio.h>
int main(){
char ch;
while((ch=getchar())!=EOF){
putchar(ch);
}
char ch2 = 'A';
printf("ch2=======>%c\n",ch2);
ch2 = getchar();
printf("ch2=======>%d\n",ch2);
return 0;
}
I don't understand why it skips the ch2=getchar() input, and I get ch2 == -1 which is the value of EOF. I tried to solve this by adding another getchar() before ch2=getchar(), but I still get ch2 == -1. Why is it and how to fix it? Thanks for helping.
I'm using MacOS.
When compiling, always enable all the warnings, then fix those warnings
I used this version of your code, which cleanly compiles:
#include <stdio.h>
int main(){
int ch;
while((ch=getchar())!=EOF){
putchar(ch);
}
int ch2 = 'A';
printf("ch2=======>%c\n",ch2);
ch2 = getchar();
printf("ch2=======>%d\n",ch2);
return 0;
}
then entered:
ddd<ctrl-d>ccc<cr>
this is the expected (and actual) result:
ddd
ddd
ch2=======>A
ccc
ch2=======>99
Notes:
1) getchar() does not return until a <cr> or <ctrl-d> is entered
2) all entered characters are echo'd by the terminal driver (not the program)
3) there are still 2 cs and a <cr> in the input buffer that have not been consumed
There is nothing surprising. Your loop
while((ch=getchar())!=EOF){
putchar(ch);
}
exhausts stdin completely. Then printf() adds some data to stdout, but stdin is still empty, so subsequent getchar() returns EOF.

calculation of the length of the file doesn't work

#include "stdio.h"
#include "stdlib.h"
int main()
{
FILE *fp;
int noOfLines =0;
char fname[]="Rtl_Prod_Id.txt";
printf(fname);
fp=fopen(fname,"r");
char ch;
//looping for every line
do {
ch=fgetc(fp);
if (ch=='\n')
noOfLines++;
} while(ch!=EOF);
//line before the last line
if (ch!='\n'&&noOfLines!=0)
noOfLines++;
fclose(fp);
printf("%d",noOfLines);
return 0;
}
I am just trying to calculate the number of lines in my file . The Same doesn't not return me any result .
What are the possible mistakes which i am doing
Environment : AIX and Compiler : CC
Thanks
Edit : My program compiles succesfully but while execute the .Out file it doesn't turn up anything
P.S : Although i got the answer . thanks to https://stackoverflow.com/users/434551/r-sahu . I had change char ch; to int ch; . but i wonder why ? What is wrong in char declaration ? . As i going to check for '\n' and EOF characters why integer then ?
The problem is that char on AIX is actually unsigned char.
fgetc() returns an int value and -1 is (typically) used to signal EOF. However, because unsigned char cannot be negative (EOF becomes 255), so the comparison ch != EOF will always be true and this causes an endless loop.
Defining int ch; fixes the problem; btw, this should have shown up during compilation if you use -Wall (show all compiler warnings).
This is a wild shot but changing the line
char ch;
to
int ch;
is appropriate. The return type of fgetc is int, not char.
You should use <...> instead of "..." to include system header files such as stdio.h or stdlib.h.
You should check the return value of fopen for possible error.
The return type of fgetc() is int, not char.
There is a logical flaw in your last line adaption. After the before do {} while loop, ch is EOF, it never will be '\n'. You need another flag to remember if there is any characters after the last '\n', and set it properly in your do {} while loop.
Here is a fixed version of your code, a little more flexible:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
int noOfLines, isRem, ch;
if (argc > 1) {
fp = fopen(argv[1],"r");
if (fp == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
}
else {
fp = stdin;
}
noOfLines = 0;
isRem = 0;
//looping for every line
do {
ch = fgetc(fp);
if (ch != EOF)
isRem = 1;
if (ch == '\n') {
noOfLines++;
isRem = 0;
}
} while (ch != EOF);
//line before the last line
if (isRem)
noOfLines++;
if (argc > 1)
fclose(fp);
printf("%d\n", noOfLines);
exit(EXIT_SUCCESS);
}
Testing:
$ wc -l t000.c
44 t000.c
$ ./a.out t000.c
44
$ echo -e "abc\ndef" | ./a.out
2
$ echo -ne "abc\ndef" | ./a.out
2
I had change char ch; to int ch; . but i wonder why ? What is wrong in
char declaration ? . As i going to check for '\n' and EOF characters
why integer then ?
EOF has a value of -1, and is of type INT, hence ch must be of type INT too.
Also, the prototype of getchar() is
int getchar(void);
so the return of getchar() must always be checked with an integer type.
There is an inherent confusion of EOF, read more about it here

print multiple lines by getchar and putchar

Im a beginner learning The C Programming language and using Microsoft visual C++ to write and test code.
Below program in C from text(section 1.5.1) copy its input to its output through putchar() and getchar():
#include <stdio.h>
int main(void)
{ int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;}
The program print characters entered by keyboard every time pressing ENTER.As a result,I can only enter one line before printing. I can't find a way to enter multi-line text by keyboard before printing.
Is there any way and how to let this program input and output multi-line text from keyboard?
Sorry if this is a basic and ignorant question.
Appreciate your attention and thanks in advance.
Some clever use of pointer arithmetic to do what you want:
#include <stdio.h> /* this is for printf and fgets */
#include <string.h> /* this is for strcpy and strlen */
#define SIZE 255 /* using something like SIZE is nicer than just magic numbers */
int main()
{
char input_buffer[SIZE]; /* this will take user input */
char output_buffer[SIZE * 4]; /* as we will be storing multiple lines let's make this big enough */
int offset = 0; /* we will be storing the input at different offsets in the output buffer */
/* NULL is for error checking, if user enters only a new line, input is terminated */
while(fgets(input_buffer, SIZE, stdin) != NULL && input_buffer[0] != '\n')
{
strcpy(output_buffer + offset, input_buffer); /* copy input at offset into output */
offset += strlen(input_buffer); /* advance the offset by the length of the string */
}
printf("%s", output_buffer); /* print our input */
return 0;
}
And this is how I use it:
$ ./a.out
adas
asdasdsa
adsa
adas
asdasdsa
adsa
Everything is parroted back :)
I've used fgets, strcpy and strlen. Do look those up as they are very useful functions (and fgets is the recommended way to take user input).
Here as soon as you type '+' and press enter all the data you entered till then is printed. You can increase the size of array more then 100
#include <stdio.h>
int main(void)
{ int c='\0';
char ch[100];
int i=0;
while (c != EOF){
c = getchar();
ch[i]=c;
i++;
if(c=='+'){
for(int j=0;j<i;j++){
printf("%c",ch[j]);
}
}
}
return 0;
}
You can put a condition on '+' char or whatever character you would like to represent print action so that this character is not stored in the array ( I have not put any such condition on '+' right now)
Use setbuffer() to make stdout fully buffered (up to the size of the buffer).
#include <stdio.h>
#define BUFSIZE 8192
#define LINES 3
char buf[BUFSIZE];
int main(void)
{ int c;
int lines = 0;
setbuffer(stdout, buf, sizeof(buf));
while ((c = getchar()) != EOF) {
lines += (c == '\n');
putchar(c);
if (lines == LINES) {
fflush(stdout);
lines = 0;
}}
return 0;}
Could you use the GetKeyState function to check if the SHIFT key is held down as you press enter? That was you could enter multiple lines by using SHIFT/ENTER and send the whole thing using the plain ENTER key. Something like:
#include <stdio.h>
int main(void)
{ int c;
while (true){
c = getChar();
if (c == EOF && GetKeyState(VK_LSHIFT) {
putchar("\n");
continue;
else if(c == EOF) break;
else {
putchar(c);
}
}

Resources