I have a question, I tried to copy one line from a pointer to file but there is one error that says that I cannot compare a interger with a pointer, can anyone help me? The error is in line ch = getc(file1); and while(ch != EOF)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#define GetCurrentDir getcwd //get the path of file
#define BUFFER_LEN 1024
int main(){
char cCurrentPath[FILENAME_MAX]; //get
char line[BUFFER_LEN]; //get command line
char* argv[100]; //user command
char* path= "/bin/"; //set path at bin
char *ch;
char progpath[20]; //full file path
int argc; //arg count
FILE *file1, *file2; //Files for history
int delete_line, count=0; //line to delete and counter
while(1){
file1 = fopen("fileOne","w");
if(GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
printf("%s",cCurrentPath);
}
printf("/SimpleShell>> "); //print shell prompt
if(!fgets(line, BUFFER_LEN, stdin))
{ //get command and put it in line
break; //if user hits CTRL+D break
}
else if(line, BUFFER_LEN, SIGQUIT){
fopen("fileOne.c","r");
ch = getc(file1);
while(ch != EOF){
printf("%s",ch);
}
}
if(count<20)
{
fputs(argv[100] ,file1);
}
else{
fclose(file1);
file1 = fopen("fileOne.c","r");
rewind(file1);
file2 = fopen("repicla.c","w");
ch = getc(file1);
while(ch != EOF){
ch = getc(file1);
if(ch != "\n"){
count++;
if(count != 20){
putc(ch, file2);
}
}
}
fclose(file1);
fclose(file2);
remove("fileOne.c");
rename("replica.c","fileOne.c");
fputs(argv[100] ,file1);
}
Change the type of ch from char * to int.
7.21.7.5 The getc function
Synopsis
1 #include <stdio.h>
int getc(FILE *stream);
Description
2 The getc function is equivalent to fgetc, except that if it is implemented as a macro, it
may evaluate stream more than once, so the argument should never be an expression
with side effects.
Returns
3 The getc function returns the next character from the input stream pointed to by
stream. If the stream is at end-of-file, the end-of-file indicator for the stream is set and
getc returns EOF. If a read error occurs, the error indicator for the stream is set and
getc returns EOF.
C 2011 Standard, Online Draft
You will need to use %c instead of %s to print out ch; additionally, the following will result in an infinite loop
ch = getc(file1);
while(ch != EOF){
printf("%s",ch);
}
because you're not updating ch in the body of the loop. Change that to
while ( ( ch = getc( file1 ) ) != EOF )
printf( "%c", ch );
Related
I'm trying to copy words from one file to another, but the words must begin with the given letter. It's working but doesn't copy every word that matches.
#include <stdio.h>
int main() {
FILE *f = fopen("words.txt", "r");
FILE *f2 = fopen("words_copy.txt", "a+");
char usr;
printf("enter letter: ");
scanf("%c", &usr);
char buffer[255];
char ch, ch2;
while ((ch = fgetc(f)) != EOF) {
ch2 = fgetc(f);
if (ch2 == usr && ch == '\n') {
fputc(ch2, f2);
fgets(buffer, sizeof(buffer), f);
fputs(buffer, f2);
}
}
return 0;
}
Words.txt contains:
adorable aesthetic alluring angelic appealing arresting attractive
blooming charismatic charming cherubic chocolate-box classy contagious
cute dazzling debonair decorative delectable delicate distinguished
enchanting enticing eye-catching glamorous glossy good-looking
gorgeous infectious lovely lush magnetic magnificent majestic melting
mesmerizing noble picturesque poetic prepossessing shimmering striking
stunning winsome
every word is in next line,
when I'm running the program and giving the letter m words_copy.txt contains only:
magnificent melting
How to fix to copy every word with matching letter?
The test in the loop is incorrect: you check the first letter after a newline and output the line if there is a match. With this logic:
you cannot match the first word in the file
you only match words starting with usr
and the word following a match is ignored
Furthermore, you ch and ch2 should be defined with type int to match EOF reliably, you should test for fopen failure and close the files after use.
You should use a simpler approach:
read a word
test if it contains the letter
output the word if it matches
Here is a modified version:
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char usr;
char buffer[256];
int ch = 0;
size_t pos;
FILE *f = fopen("words.txt", "r");
if (f == NULL) {
fprintf(stderr, "cannot open words.txt: %s\n", strerror(errno));
return 1;
}
FILE *f2 = fopen("words_copy.txt", "a+");
if (f2 == NULL) {
fprintf(stderr, "cannot open words_copy.txt: %s\n", strerror(errno));
fclose(f);
return 1;
}
printf("enter letter: ");
if (scanf(" %c", &usr) != 1) {
fprintf(stderr, "missing input\n");
fclose(f);
fclose(f2);
return 1;
}
while (ch != EOF) {
pos = 0;
/* read a word, stop at whitespace and end of file */
while ((ch = fgetc(f)) != EOF && !isspace(ch)) {
if (pos + 1 < sizeof(buffer))
buffer[pos++] = (char)ch;
}
buffer[pos] = '\0';
/* test for a match */
if (strchr(buffer, usr)) {
/* output matching word */
fprintf(f2, "%s\n", buffer);
}
}
fclose(f);
fclose(f2);
return 0;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "function.h"
int main()
{
int nl, nw, nc;
nl = nw = nc = 0;
char filename[100];
printf("ENTER FILE NAME: ");
scanf("%s", filename);
FILE *fp = fopen(filename, "r");
if(fp == NULL)
{
printf("OPEN FAIL");
exit(0);
}
nc = character(fp);
nw = word(fp);
nl = line(fp);
printf("number of characters: %d\n", nc);
printf("number of words: %d\n", nw);
printf("number of lines: %d\n", nl);
fclose(fp);
return 0;
}
character.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int character(FILE *fp)
{
int nc = 0;
char ch;
while((ch=fgetc(fp)) != EOF)
{
if(ch != ' ' && ch != '\t' && ch != '\n' && ch != '\0')
{
nc++;
}
}
return nc;
}
word.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int word(FILE *fp)
{
int nw = 0;
char ch;
while((ch=fgetc(fp)) != EOF)
{
if(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0')
{
nw++;
}
}
return nw;
}
line.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int line(FILE *fp)
{
int nl = 0;
char ch;
while((ch=fgetc(fp)) != EOF)
{
if((ch == '\n' || ch == '\0'))
{
nl += 1;
}
}
return nl;
}
function.h
int line(FILE *fp);
int word(FILE *fp);
int character(FILE *fp);
execution results
ENTER FILE NAME: test.txt
number of characters: 36
number of words: 0
number of lines: 0
My program counts the number of characters correctly but not of the words nor lines.
It seems strange to me because I think that the basic structure of codes for word and line counter shouldn't be so different from that for the characters.
I think that I only have to change the conditions of the if when I count the numbers of words and lines.
Most of all, at least, the program should give me some number other than mere zeros since the text file definitely contains spaces and new lines.
What do you think the problems here?
FYI the text file I used for testing is
test test test
test test test
test test test
Once you have called the character function, the file is at its end. The next attempt to read from the file will result in EOF.
You need to seek back to the beginning again if you want to start reading it all over.
On another couple of notes, first remember that fgetc return an int, which is rather important for the comparison against the int value EOF.
Secondly you don't need three different function and three different loops. You can count all statistics in one single loop.
I try to count the number of characters, words, lines in a file.
The txt file is:
The snail moves like a
Hovercraft, held up by a
Rubber cushion of itself,
Sharing its secret
And here is the code,
void count_elements(FILE* fileptr, char* filename, struct fileProps* properties) // counts chars, words and lines
{
fileptr = fopen(filename, "rb");
int chars = 0, words = 0, lines = 0;
char ch;
while ((ch = fgetc(fileptr)) != EOF )
{
if(ch != ' ') chars++;
if (ch == '\n') // check lines
lines++;
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') // check words
words++;
}
fclose(fileptr);
properties->char_count = chars;
properties->line_count = lines;
properties->word_count = words;
}
But when i print the num of chars, words and lines, outputs are 81, 18, 5 respectively
What am i missing?
(read mode does not changes anything, i tried "r" as well)
The solution I whipped up gives me the same results as the gedit document statistics:
#include <stdio.h>
void count_elements(char* filename)
{
// This can be a local variable as its not used externally. You do not have to put it into the functions signature.
FILE *fileptr = fopen(filename, "rb");
int chars = 0, words = 0, lines = 0;
int read;
unsigned char last_char = ' '; // Save the last char to see if really a new word was there or multiple spaces
while ((read = fgetc(fileptr)) != EOF) // Read is an int as fgetc returns an int, which is a unsigned char that got casted to int by the function (see manpage for fgetc)
{
unsigned char ch = (char)read; // This cast is safe, as it was already checked for EOF, so its an unsigned char.
if (ch >= 33 && ch <= 126) // only do printable chars without spaces
{
++chars;
}
else if (ch == '\n' || ch == '\t' || ch == '\0' || ch == ' ')
{
// Only if the last character was printable we count it as new word
if (last_char >= 33 && last_char <= 126)
{
++words;
}
if (ch == '\n')
{
++lines;
}
}
last_char = ch;
}
fclose(fileptr);
printf("Chars: %d\n", chars);
printf("Lines: %d\n", lines);
printf("Words: %d\n", words);
}
int main()
{
count_elements("test");
}
Please see the comments in the code for remarks and explanations. The code also would filter out any other special control sequences, like windows CRLF and account only the LF
Your function takes both a FILE* and filename as arguments and one of them should be removed. I've removed filename so that the function can be used with any FILE*, like stdin.
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
typedef struct { /* type defining the struct for easier usage */
uintmax_t char_count;
uintmax_t word_count;
uintmax_t line_count;
} fileProps;
/* a helper function to print the content of a fileProps */
FILE* fileProps_print(FILE *fp, const fileProps *p) {
fprintf(fp,
"chars %ju\n"
"words %ju\n"
"lines %ju\n",
p->char_count, p->word_count, p->line_count);
return fp;
}
void count_elements(FILE *fileptr, fileProps *properties) {
if(!fileptr) return;
properties->char_count = 0;
properties->line_count = 0;
properties->word_count = 0;
char ch;
while((ch = fgetc(fileptr)) != EOF) {
++properties->char_count; /* count all characters */
/* use isspace() to check for whitespace characters */
if(isspace((unsigned char)ch)) {
++properties->word_count;
if(ch == '\n') ++properties->line_count;
}
}
}
int main() {
fileProps p;
FILE *fp = fopen("the_file.txt", "r");
if(fp) {
count_elements(fp, &p);
fclose(fp);
fileProps_print(stdout, &p);
}
}
Output for the file you showed in the question:
chars 93
words 17
lines 4
Edit: I just noticed your comment "trying to count only alphabetical letters as a char". For that you can use isalpha and replace the while loop with:
while((ch = fgetc(fileptr)) != EOF) {
if(isalpha((unsigned char)ch)) ++properties->char_count;
else if(isspace((unsigned char)ch)) {
++properties->word_count;
if(ch == '\n') ++properties->line_count;
}
}
Output with the modified version:
chars 74
words 17
lines 4
A version capable of reading "wide" characters (multibyte):
#include <locale.h>
#include <stdint.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
typedef struct {
uintmax_t char_count;
uintmax_t word_count;
uintmax_t line_count;
} fileProps;
FILE* fileProps_print(FILE *fp, const fileProps *p) {
fprintf(fp,
"chars %ju\n"
"words %ju\n"
"lines %ju\n",
p->char_count, p->word_count, p->line_count);
return fp;
}
void count_elements(FILE *fileptr, fileProps *properties) {
if(!fileptr) return;
properties->char_count = 0;
properties->line_count = 0;
properties->word_count = 0;
wint_t ch;
while((ch = fgetwc(fileptr)) != WEOF) {
if(iswalpha(ch)) ++properties->char_count;
else if(iswspace(ch)) {
++properties->word_count;
if(ch == '\n') ++properties->line_count;
}
}
}
int main() {
setlocale(LC_ALL, "sv_SE.UTF-8"); // set your locale
FILE *fp = fopen("the_file.txt", "r");
if(fp) {
fileProps p;
count_elements(fp, &p);
fclose(fp);
fileProps_print(stdout, &p);
}
}
If the_file.txt contains one line with öäü it'll report
chars 3
words 1
lines 1
and for your original file, it'd report the same as above.
In this program, how i do at the same time convert the uppercase letters to lowercase letters and lowercase letters to uppercase letter?
I have tried many times but it is not working.
My expectations, Suppose for example
Input:
from read.txt(orginal contant of the file:
Hello World)
Output
hELLO wORLD
This is my code....
(I can only convert from uppercase to lowercase. At the same time I could not convert from uppercase to lowercase and lowercase to uppercase).
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE* file;
char ch;
file = fopen("read.txt","r");
while (ch != EOF)
{
ch = toupper(ch);
printf("%c", ch);
ch = fgetc(file);
}
fclose(file);
return 0;
}
you have plenty errors here.
your first check the not initialized ch variable, you use it and try to print, then you read it. The order has to be right opposite.
ch has to be of type int to accommodate EOF
you need to check if the fopen was successful
int main()
{
FILE* fptr;
int ch;
fptr = fopen("read.txt","r");
if(fptr)
{
while ((ch = fgetc(fptr)) != EOF)
{
ch = toupper(ch);
printf("%c", ch);
}
fclose(fptr);
}
return 0;
}
// Note that UPPER and lower chars differ by bit 5 (value 0x20).
// If you want to switch case for any [A-Za-z] in one step,
// an exclusive-OR (^ bitwise operator) can be used:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define TOGGLE_CASE(c) ((c) ^ 0x20)
int
main(void)
{
FILE *file;
char ch;
if ((file = fopen("read.txt", "r")) == NULL) {
dprintf(2, "fopen error\n");
return (1);
}
while ((ch = fgetc(file)) != EOF)
printf("%c", isalpha(ch) ? TOGGLE_CASE(ch) : ch);
fclose(file);
return (0);
}
it's about reading from a text file.
I have 3 command line arguments:
name of text file
delay time
how many line(s) want to read.
I want to read that text file by user specified line numbers till text file ends.
For example, the first time I read 5 lines and then the program asks how many line(s) do you want to read?. I would enter 7 it reads lines 5 to 12.
This would repeat until the end of the file.
#include <stdlib.h>
#include <stdio.h>
#include<time.h>
#include <string.h>
void delay(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
int countlines(const char *filename) {
FILE *fp = fopen(filename, "r");
int ch, last = '\n';
int lines = 0;
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
lines++;
last = ch;
}
fclose(fp);
if (last != '\n')
lines++;
}
return lines;
}
int main(int argc, char *arg[])
{
FILE *ptDosya;
char ch;
ch = arg[1][0];
int s2;
int satir = 0;
int spaceCounter=0;
int lineCount, x = 0;
lineCount = atoi(arg[3]);
s2 = atoi(arg[2]);
printf("dosya %d satir icerir.\n", countlines(arg[1]));
ptDosya = fopen(arg[1], "r");
if (ptDosya != NULL)
{
while (ch != EOF&& x < lineCount)
{
ch = getc(ptDosya);
printf("%c", ch);
if (ch == '\n')
{
delay(s2);
x++;
}
}
while (x < countlines(arg[1]))
{
printf("satir sayisi giriniz:");
scanf("%d", &lineCount);
// i don't know what should i do in this loop..
x=x+lineCount;
}
}
else {
printf("dosya bulunamadi");
}
printf("\n\nend of file!\n");
fclose(ptDosya);
return 0;
system("PAUSE");
}
Your delay function uses a busy loop. This is unnecessarily expensive in terms of computing power. It would be very unwelcome to do this on a battery operated device. Furthermore, clock() does not necessarily return a number of milliseconds. The unit used by the clock() function can be determined using the CLOCKS_PER_SEC macro. Unfortunately, there is no portable way to specify a delay expressed in milliseconds, POSIX conformant systems have usleep() and nanosleep().
Your line counting function is incorrect: you count 1 line too many, unless the file ends without a trailing linefeed.
Here is an improved version:
int countlines(const char *filename) {
FILE *fp = fopen(filename, "r");
int ch, last = '\n';
int lines = 0;
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
lines++;
last = ch;
}
fclose(fp);
if (last != '\n')
lines++;
}
return lines;
}
There are issues in the main() function too:
You so not verify that enough arguments are passed on the command line.
You do not check for EOF in the main reading loop.
You do not repeat the process in a loop until end of file, nor do you even ask the question how many line(s) do you want to read? after reading the specified number of lines...
First, if the file cannot be found, the countlines method returns zero. You should use that value to write the error message, and skip the rest of the code.
Second, in the next loop, you use
if (ch != '\n') {
printf("%c", ch);
} else {
printf("\n");
delay(s2);
x++;
}
Why the two printf statements? They will print the same thing.
Perhaps something like this:
ch = getc(ptDosya);
/* exit the loop here if you hit EOF */
printf("%c", ch); /* Why not putc() or putchar() ? */
if (ch == '\n') {
x++;
if ( x == lineCount ) {
x = 0;
lineCount = requestNumberOfLinesToRead();
} else {
sleep(s2); /* instead of delay(). Remember to #include unistd.h */
}
}