How to display characters read from a file using getc() - c

When I try to read input from a file named "file1", my program correctly displays
the number of characters in the file, but in an unrecognized character format.
Below is the code
#include <stdio.h>
#include <stdlib.h>
void db_sp(FILE*);
int main(int argc,char *argv[])
{
FILE *ifp,*ofp;
if(argc!=2) {
fprintf(stderr,"Program execution form: %s infile\n",argv[0]);
exit(1);
}
ifp=fopen(argv[1],"r");
if (ifp==NULL) printf("sdaf");
//ofp=fopen(argv[2],"w+") ;
db_sp(ifp);
fclose(ifp);
//fclose(ofp);
return 0;
}
void db_sp(FILE *ifp)
{
char c;
while(c=getc(ifp) !=EOF) {
//printf("%c",c);
putc(c,stdout);
if(c=='\n' || c=='\t' || c==' ')
printf("%c",c);
}
}

The problem is here:
while(c=getc(ifp) !=EOF){
Because of operator precendence, this getc(ifp) !=EOF gets executed first. Then c = <result of comparison> gets executed. Which is not the order you want.
Use parentheses to force the correct order.
while((c=getc(ifp)) !=EOF) {
Other notes:
getc returns an int so you should change the type of c to int.
Also, if you fail to open the file, you still continue execution. You should gracefully exit on failure.

Related

How to Display Content of Multiple FIles Given in command Line argument in C

So I am trying to print the content of files which are given as an argument and the problem i am facing is when multiple arguments are passed it display the content of first file only.
Like if i give Input as a.txt b.txt c.txt it displays the output of a.txt and ends
the code i have written so far is:
#include<stdio.h>
int main(int argc,char*argv[])
{
if(argc<3)
{
printf("Insufficent Arguments");
exit(0);
}
int i;
FILE *fp;
char c;
for(i=1;i<argc;i++)
{
fp=fopen(argv[i],"r");
if (fp == NULL )
{
fprintf( stderr, "could not open file named %s!\n",argv[i] );
return 2;
}
else
{
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
}
fclose( fp );
}
}
This code is after all possible modifications i have tried to resolve the problem
Please can anyone guide me what am i doing wrong?
After the first loop, you need to reset c. If you don't it keeps the last value from the previous file.
Also c needs to be int.
pseudo code
int main(int argc, char **argv) {
int c;
for (int i = 1; i < argc; i++) {
c = 0;
while (c != EOF) {
/* ... */
}
}
}
You may want to re-initialize your char 'c', that is used to check EOF.
After first iteration/file, it ends up with EOF and since this char is declared outside it retains its value across files. So for other file it will never go inside while loop.
option 1: Move your char c; declaration inside else
Or
option 2: re-initialize your c before while, c = fgetc(fp); (yes, you will have to restructure print)

Reading files with the same extension in a directory and count their lines

I am having this problem with my code. I've been trying to open files that have the same extension and read the number of lines in the file that is in the directory.
So, here is what I've done:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int countLines(char name[]);
int main()
{
struct dirent *de;
DIR *dr=opendir(".");
char check[16]=".nkt";
int i;
char name[64];
int count=0;
if(dr==NULL)
{
printf("Didn't open!");
return 0;
}
while((de=readdir(dr))!=NULL)
{
if((strstr(de->d_name, check))!=NULL)
{
strcpy(name, de->d_name);
countLines(name);
}
}
closedir(dr);
return 0;
}
int countLines(char name[])
{
FILE *fp;
fp=fopen(name,"r");
char ch;
int lines=0;
while(!feof(fp))
{
ch=fgetc(fp);
if(ch=='\n')
{
lines++;
}
}
fclose(fp);
printf("%d\n", lines);
}
and the result that I am getting is always like :
2
2
2
Even though every file has 54 lines.
Would gladly appreciate some help.
PS. The extension is .nkt
The countLines() function you show is stepping into several traps.
fgetc() returns int not char by intention. It does this to be able to return the End-of-File state, aside all other possible character values. A simple char cannot do this.
The use of feof() to identify the End-of-File fails as the EOF indicator is set only after the last read hitting the end of the file has been completed. So a loop steered using feof() typically iterated one time to often.
A detailed discussion on this is here.
A text file's last line not necessarily carries an End-of-File indicator, but you mostly likely still want count that line. Special logic needs to be applied to cover this case.
A possible implementation of a function taking care off all those issue mentioned above might look like this:
#include <stdio.h>
/* Returns the number of lines inside the file named file_name
or -1 on error. */
long count_lines(const char * file_name)
{
long lines = 0;
FILE * fp = fopen(file_name, "r"); /* Open file to read in text mode. */
if (NULL == fp)
{
lines = -1;
}
else
{
int previous = EOF;
for (int current; (EOF != (current = fgetc(fp)));)
{
if ('\n' == current)
{
++lines;
}
previous = current;
}
if (ferror(fp)) /* fgetc() returns EOF as well if an error occurred.
This call identifies that case. */
{
lines = -1;
}
else if (EOF != previous && '\n' != previous)
{
++lines; /* Last line missed trailing new-line! */
}
fclose(fp);
}
return lines;
}
Regarding the discussion about different End-of-Line indicators inside the question's comment section:
The End-of-Line indicator for text files is implemented differently on different platforms (UNIX: '\n' vs. Windows: \r\n vs. ... (https://en.wikipedia.org/wiki/Newline)).
To manoeuvre around this the C library function fopen() by default opens a file in so called "text-mode". If opened this way the C implementation takes care that each line's end is returned as a single '\n' character, the so called "new-line" character. Please note (as mentioned above under 3.) that for the last line there might be no End-of-Line indicator at all.

Reading and writing into a file in c

I need to write into a file with uppercase some strings ,then to display on screen with lowercase. After that ,I need to write into file the new text (lowercase one). I write some code ,but it doesn't work. When I run it , my file seems to be intact and the convert to lowercase don't work
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void main(void) {
int i;
char date;
char text[100];
FILE *file;
FILE *file1;
file = fopen("C:\\Users\\amzar\\Desktop\\PC\\Pregatire PC\\Pregatire PC\\file\\da.txt","r");
file1 = fopen("C:\\Users\\amzar\\Desktop\\PC\\Pregatire PC\\Pregatire PC\\file\\da.txt","w");
printf("\nSe citeste fisierul si se copiaza textul:\n ");
if(file) {
while ((date = getc(file)) != EOF) {
putchar(tolower(date));
for (i=0;i<27;i++) {
strcpy(text[i],date);
}
}
}
if (file1) {
for (i=0;i<27;i++)
fprintf(file1,"%c",text[i]);
}
}
There are several problems with your program.
First, getc() returns int, not char. This is necessary so that it can hold EOF, as this is not a valid char value. So you need to declare date as int.
When you fix this, you'll notice that the program ends immediately, because of the second problem. This is because you're using the same file for input and output. When you open the file in write mode, that empties the file, so there's nothing to read. You should wait until after you finish reading the file before you open it for output.
The third problem is this line:
strcpy(text[i],date);
The arguments to strcpy() must be strings, i.e. pointers to null-terminated arrays of char, but text[i] and date are char (single characters). Make sure you have compiler warnings enabled -- that line should have warned you about the incorrect argument types. To copy single characters, just use ordinary assignment:
text[i] = date;
But I'm not really sure what you intend with that loop that copies date into every text[i]. I suspect you want to copy each character you read into the next element of text, not into all of them.
Finally, when you were saving into text, you didn't save the lowercase version.
Here's a corrected program. I've also added a null terminator to text, and changed the second loop to check for that, instead of hard-coding the length 27.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void main(void) {
int i = 0;
int date;
char text[100];
FILE *file;
FILE *file1;
file = fopen("C:\\Users\\amzar\\Desktop\\PC\\Pregatire PC\\Pregatire PC\\file\\da.txt","r");
printf("\nSe citeste fisierul si se copiaza textul:\n ");
if(file) {
while ((date = getc(file)) != EOF) {
putchar(tolower(date));
text[i++] = tolower(date);
}
text[i] = '\0';
fclose(file);
} else {
printf("Can't open input file\n");
exit(1);
}
file1 = fopen("C:\\Users\\amzar\\Desktop\\PC\\Pregatire PC\\Pregatire PC\\file\\da.txt","w");
if (file1) {
for (i=0;text[i] != '\0';i++)
fprintf(file1,"%c",text[i]);
fclose(file1);
} else {
printf("Can't open output file\n");
exit(1);
}
}

C, how to stop stdin from outputting after each enter by the user?

I am new to C and I am encountering a problem with stdin I cannot find a solution to. My program either reads from file(s) or reads from stdin if no arguments (files) are provided by the user.
If the user doesn't supply any arguments then it will automatically read from stdin. My program is supposed to take in input (from file or stdin) and then remove the blank lines from it.
My problem arises when the program reads from stdin. Every time the user types something then presses enter the program automatically out puts the results. When I'd prefer enter to just be a newline.
How can I make it so the program waits for the user to hit EOF instead of each enter?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHARS 1024
int main(int argc, char** argv){
int good_file = 0;
if (argc <= 1) {
good_file++;
test(stdin);
}
FILE* files[argc - 1];
int i;
for (i = 0; i < argc - 1; i++) {
if ((files[i] = fopen(argv[i + 1], "r")) == NULL) {
continue;
} else {
good_file++;
test(files[i]);
}
}
if (!good_file) {
fprintf(stderr, "ERROR!\n");
}
}
int test(FILE *file) {
char buffer[NUMCHARS];
while (fgets(buffer, NUMCHARS, file) != NULL)
part2(buffer);
fclose(file);
}
int part2(char *buffer) {
if (!is_all_white(buffer)) {
fputs(buffer, stdout);
}
}
int is_all_white(char *s) {
while (*s) {
if (!('\n' == *s || '\t' == *s || ' ' == *s))
return 0;
s += 1;
}
return 1;
}
I appreciate any feedback!
It isn't an issue with stdin per se - if you want to wait to output your data, you will have to store it. You could write it to a file and read it back afterward. You could use malloc and realloc to store the data in memory. Mainly, if you don't want the data to output on every line, you need not to output it on every line.
Pre process stdin into a temp work file, this will then give you the control you require.
Use function mkstemp.
Be warned stdin is a pipe, where as the fopen files are probably disk files

loop doesn't end while reading from a textfile

I am typing a very simple C program which reads characters from a file and displays it "encrypted" by replacing each character with the one 3 characters after (Caesar cipher).
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *inFile;
int ch;
int ch1;
if (argc!= 2){
printf("Usage: Code <inputfile> [> Outfile]\n");
return(-1);
}
inFile = fopen(argv[1], "r");
while ((ch1=toupper(fgetc(inFile)))!='\0') {
ch=ch1;
if (ch >=33 && ch <=255) //exclude special chars
ch += 3;
putchar(ch);
}
printf("END\n");
fclose(inFile);
return 0;
}
I compile it with gcc with gcc encode.c and then run ./a textfile. A line follows with the "encoded" text, then, after 2 seconds, the terminal is filled with garbage, specifically an ascii square. I escape it with Ctrl-C. Obviously the while loop never ends, since I never see the END string. I wondered whether '\0' is the problem and i replaced it with NULL but not only the problem persists, but I also receive a warning during compile.

Resources