whenever I run the program the second print statement isn't printing. I tried using a function but I'm new to C and don't really understand anything. I've also attached my activity as I'm not sure how to do the other things on it.activity photo
#include <stdio.h>
#include <string.h>
#define LINE_LENGTH 1000
int main(int argc, char **argv)
{
FILE *input_file = fopen("cstest.c", "r");
char line [LINE_LENGTH];
//while loop to ger
while (fgets(line, LINE_LENGTH, input_file) != NULL)
{
int ch = 0;//ch is the cast
int lines = 0;//start with one because
if (input_file == NULL)
return 0;
while (!feof(input_file))
{
ch = fgetc(input_file);
if (ch == '\n')
{
lines++;
}
}//end while
printf("lines: %d\n", lines);
}//end while loop
while (fgets(line, LINE_LENGTH, input_file) != NULL)
{
int ch = 0;//ch is the cast
int lines = 0;//start with one because
if (input_file == NULL)
return 0;
while (!feof(input_file))
{
int characters = 0;
char c;
for (c = getc(input_file); c != EOF; c = getc(input_file))
// Increment count for this character
characters = characters + 1;
printf("characters: %d\n", characters);
fclose(input_file);
}
}
}
Related
I have a function that returns the number of lines, characters, and words in an array. For some reason, when i loop through the array to print the values I am only getting the corrrect value for lines, the characters and words are returning as 0. All the functions are predetermined by my professor and my job is to fill them in.
int main(int argc, char **argv)
{
int *myArray = get_counts(argv[1]);
for (int i = 0; i < 3; i++)
{
printf("%d\n", myArray[i]);
}
return 0;
}
int *get_counts(char *filename)
{
FILE *file;
file = fopen(filename, "r");
if (file == NULL)
{
printf("NULL FILE");
}
char c;
int h;
bool whitespace = true;
static int arr[3] = {0,0,0};
do
{
c = fgetc(file);
if (c == '\n')
{
arr[0] ++;
}
}while (c != EOF);
while (true)
{
h = fgetc(file);
if (feof(file))
{
break;
}
else if (ferror(file))
{
printf("error reading file");
}
arr[2] ++;
if (whitespace && !isspace(h))
{
arr[1] ++;
whitespace = false;
}
else if (!whitespace &&isspace(h))
{
whitespace = true;
}
}
fclose(file);
return arr;
}
The best option is probably to just iterate through the file in one loop (you could also rewind() after the first loop). Use the return value of fgetc() to determine of you are at EOF instead of separate feof() calls. I also made the the result array an (out) argument instead of using a static variable (the latter is not reentrant if you ever want to call this from multiple threads and it's easy to do):
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
void get_counts(char *filename, int arr[3]) {
memset(arr, 0, 3 * sizeof(int));
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("NULL FILE");
return;
}
bool whitespace = true;
for(;;) {
int c = fgetc(file);
if(c == EOF)
break;
else if(c == '\n')
arr[0]++;
else if (whitespace && !isspace(c)) {
arr[1]++;
whitespace = false;
} else if (!whitespace && isspace(c))
whitespace = true;
arr[2]++;
}
fclose(file);
}
int main(int argc, char **argv) {
int myArray[3];
get_counts(argv[1], myArray);
for (int i = 0; i < 3; i++) {
printf("%d\n", myArray[i]);
}
}
The output on the above file is:
39
94
715
The word count 94 doesn't agree with wc -w but you could be using a different definition of what a word is.
It's a good idea to separate calculations and i/o, so consider opening and closing the file in main() and pass in the file handle. It becomes easy, for instance, to use the stdin file handle instead if you don't want to use a physical file.
After the first do-while loop the condition EOF occurs.
do
{
c = fgetc(file);
if (c == '\n')
{
arr[0] ++;
}
}while (c != EOF);
So the following while loop has no effect.
You should use only one loop to count lines, words and characters.
Pay attention to that the variable c should be declared as having the type int
int c;
Also you need to exit the function if the file was not opened.
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.
I have used comma as a separator after every string
fp=fopen("log.dat","ab");
fprintf(fp,"%s%c",enteredUsername,',');
fclose(fp);
Reading from file:
fp=fopen("log.dat","rb");
int c;
while ((c = fgetc(fp)) != EOF)
printf("%c", c);
How can I:
1.Avoid reading the final character inside the file,
2.Check if file is empty?
You can use a one-character buffer like this:
#include <stdio.h>
int main(void)
{
FILE *fp = fopen("log.dat", "rb");
if(fp == NULL) return;
int prev = -1000;
int c;
while ((c = fgetc(fp)) != EOF) {
if(prev >= 0) {
printf("%c", prev);
}
prev = c;
}
fclose(fp);
return 0;
}
Input log.dat
one,two,three,
Output
one,two,three
Why you want to avoid reading the final character? You can use the EOF in order to check if a file is empty.
if( (c= fgetc(fp)) == EOF){
//do stuff
}
else{
printf("File is empty\n")
return 0;
}
That worked for me.
#include <stdio.h>
int main(void) {
unsigned counter;
for( counter=0; 1; counter++) {
int ch;
char lastchar;
ch = getc(stdin);
if (ch == EOF) break;
if (counter) putc( lastchar, stdout);
lastchar = ch;
}
if (!counter) fprintf(stderr,"File was empty\n" );
else fprintf(stderr,"Read %u characters.\n", counter );
return 0;
}
// Test it with:
// echo -n "a,b,c," >bagger
// ./a.out <bagger
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 */
}
}
I have this small program in C that reads through a file a compares word by word,
how can I assure that words like "this," won't be read as a word? I would like it to read as "this"
int main(int argc, char *argv[]) {
if(argc != 3)
{
printf("Usage: ./sw <word> <filename> \n");
exit(1);
}
char* word = argv[1];
const char* filename = argv[2];
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
char w[250], check_eof;
do
{
check_eof = fscanf(file, "%s", w);
if(strcmp(word, w) == 0)
{
printf("W : %s \n", w);
}
} while(check_eof != EOF);
fclose(file);
return 0;
}
You can check if a char belongs to a word like this
int c = fgetc(file);
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
// c belongs to a word
word[n++] = c;
} else {
// end of word
if (strncmp(word, w, n) == 0) {
// word and w match!
}
}
If you #include <ctype.h>, then you can call isalpha(c) instead to test it.
In the code below, I use isalpha() and I copy the result string in a new buffer named res. However, this procedure can be done in-place, but I'll leave now for the sake of simplicity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // for isalpha()
int main(int argc, char *argv[]) {
char* word = "this";
const char* filename = "test.txt";
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
// ATTENTION, it is 249 chars, do NOT forget of the null terminator
char w[250], res[250];
int check_eof; // should be of type int, for EOF checking
do
{
check_eof = fscanf(file, "%s", w);
// what if 'word' appears as the last word
// in the file? You should check for eof
// right after fscanf()
if(check_eof == EOF)
break;
int i = 0, j = 0;
while (w[i]) // parse what we read
{
if (isalpha(w[i]))
res[j++] = w[i]; // keep only the alphabetic chars
i++;
}
res[j] = '\0'; // it should be a null terminated string
if(strcmp(word, res) == 0) // compare to 'res' now
{
printf("W : %s \n", res);
}
} while(1); // the terminating step is inside the body now
fclose(file);
return 0;
}