Using file and loop in c - c

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);
}

Related

Counting chars, words and lines in a file

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.

Compare between pointers and integer

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 );

C programming- read from text file

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 */
}
}

Incompatible types in assignment of int to char

void trinti1()
{
int b,lines;
char ch[20];
FILE* file = fopen ("Kordinates.txt", "r");
while(!feof(file))
{
ch = fgetc(file);
if(ch == '\n')
{
lines++;
}
}
fclose(file);
}
Hello guys I am trying to count lines in file, but seems fgetc(file) returns int and it can't be converted to char. Help me what I am doing wrong?
In your code ch is not a char, it is char[20] - an array of 20 characters. You cannot assign a result of fgetc to it, because fgetc returns an int (which contains either a single char, or an EOF mark).
Change the declaration of ch to int ch to fix this problem. You can also drop the call to feof because it happens at the wrong time anyway (you call it after read operations, not before read operations).
for (;;) {
int ch = fgetc(file);
if (ch == EOF) break;
if (ch == '\n') lines++;
}
void trinti1()
{
int b,lines=0;
int ch;
FILE* file = fopen ("Kordinates.txt", "r");
while(EOF!=(ch=fgetc(file)))
{
if(ch == '\n')
{
++lines;
}
}
fclose(file);
}

Reading a UTF-16 CSV file by char

Currently I am trying to read a UTF-16 encoded CSV file char by char, and convert each char into ascii so I can process it. I later plan to change my processed data back to UTF-16 but that is besides the point right now.
I know right off the bat I am doing this completely wrong, as I have never attempted anything like this before:
int main(void)
{
FILE *fp;
int ch;
if(!(fp = fopen("x.csv", "r"))) return 1;
while(ch != EOF)
{
ch = fgetc(fp);
ch = (wchar_t) ch;
ch = (char) ch;
printf("%c", ch);
}
fclose(fp);
return 0;
}
Wishfully thinking, I was hoping that that work by magic for some reason but that was not the case. How can I read a UTF-16 CSV file and convert it to ascii? My guess is since each utf-16 char is two bytes (i think?) I'm going to have to read two bytes at a time from the file into a variable of some datatype which I am not sure of. Then I guess I will have to check the bits of this variable to make sure it is valid ascii and convert it from there? I don't know how I would do this though and any help would be great.
You should use fgetwc. The below code should work in the presence of a byte-order mark, and an available locale named en_US.UTF-16.
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
main() {
setlocale(LC_ALL, "en_US.UTF-16");
FILE *fp = fopen("x.csv", "rb");
if (fp) {
int order = fgetc(fp) == 0xFE;
order = fgetc(fp) == 0xFF;
wint_t ch;
while ((ch = fgetwc(fp)) != WEOF) {
putchar(order ? ch >> 8 : ch);
}
putchar('\n');
fclose(fp);
return 0;
} else {
perror("opening x.csv");
return 1;
}
}
This is my solution thanks to the comments under my original question. Since every character in the CSV file is valid ascii the solution was simple as this:
int main(void)
{
FILE *fp;
int ch, i = 1;
if(!(fp = fopen("x.csv", "r"))) return 1;
while(ch != EOF)
{
ch = fgetc(fp);
if(i % 2) //ch is valid ascii
i++;
}
fclose(fp);
return 0;
}

Resources