Basic File IO in C Produces all a's - c

I am using CodeBlocks on Windows to compile.
Why the program gives me this answer? Why there are so much as and don't get the answer 123456abcdef?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp;
char s[100] = "abcdef";
char c1 = '0';
int i = 0;
fp = fopen("ot.txt", "w");
if (fp == NULL) {
printf("file open error");
exit(0);
}
while (s[i] != '\0') {
fputc(s[i], fp);
i++;
printf("%d", i);
}
while (c1 != EOF) {
c1 = fgetc(fp);
putchar(c1);
}
fclose(fp);
}

There are multiple problems in your code:
c1 should be defined with type int to accommodate for all values returned by fgetc(). a char cannot unambiguously store EOF.
You should open the file in write+update mode "w+"
You should rewind the stream pointer before reading back from it for 2 reasons: a seek operation is required between read and write operations and you want to read the characters from the start of the file.
You need to test for EOF after reading a byte with fgetc(), otherwise you will output the EOF converted to unsigned char to stdout before exiting the loop.
It is good style to return 0; from main() to indicate success and non-zero to indicate failure.
Here is a corrected version:
#include <stdio.h>
int main(void) {
FILE *fp;
char s[] = "abcdef";
int i, c;
fp = fopen("ot.txt", "w+");
if (fp == NULL) {
printf("file open error\n");
return 1;
}
i = 0;
while (s[i] != '\0') {
fputc(s[i], fp);
i++;
printf("%d", i);
}
rewind(fp);
while ((c1 = fgetc(fp)) != EOF) {
putchar(c1);
}
printf("\n");
fclose(fp);
return 0;
}

Related

How to replace a character in text file using C?

I need to read a text file (E3-5.txt), and search for character c1 to be replaced by c2.
This is my incomplete code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char c;
char c1 = 'm';
char c2 = 'a';
int i;
FILE* fp;
fp = fopen("C:\\E3-5.txt", "r+");
if (fp == NULL)
{
printf("File not found!");
return 0;
}
for(c = getc(fp); c != EOF; c = getc(fp))
{
if(c == 'm')
{
i = ftell(fp);
printf("\nPosition %d", i);
}
}
}
I am having trouble how to locate the position of c1 in the text and how to rewrite it.
Edit:
I used the code from the answer, but it didn't change the text.
This is the new code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char c;
char c1 = 'm';
char c2 = 'a';
int i;
FILE* fp;
fp = fopen("C:\\E3-5.txt", "rb+");
if (fp == NULL)
{
printf("File not found!");
return 0;
}
else
{
for(c = getc(fp); c != EOF; c = fgetc(fp))
{
if(c == c1)
{
fseek(fp, -1, SEEK_CUR);
fputc(c2, fp);
}
else
{
return 0;
}
}
}
return 0;
}
The program returned 0 without writing anything in the text
Here you have a very naive one:
int freplace(FILE *f, char needle, char repl)
{
int result = 1;
int c;
if(f)
{
while((c = fgetc(f)) != EOF)
{
if(c == needle)
{
fseek(f, -1, SEEK_CUR);
fputc(repl, f);
//all I/O functions require error handling
}
}
}
return result;
}
getc() returns an int so you need to declare int c not char c to check for the EOF.
ftell() gets the location. Use fwrite() or fputc() to write to file at that location by setting with fseek().
Go to https://en.cppreference.com/w/c for reference. Lots of beginners fail to read all of the standard library functions, and some even reinvent the wheel.
You really don't want to directly manipulate a file. Ever. Doing so is just asking for data corruption. Instead, create a new file and move it when you're done. Also, it's a lot easier to write the code. You can do so with something like:
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int c1 = argc > 1 ? argv[1][0] : 'm';
int c2 = argc > 2 ? argv[2][0] : 'a';
const char *path = argc > 3 ? argv[3] : "stdin";
FILE *in = argc > 3 ? fopen(path, "r") : stdin;
if( in == NULL ){
perror(path);
return 1;
}
FILE *out = stdout;
char tmp[1024] = ".tmpXXXXX";
char *outpath = "stdout";
if( argc > 3 ){
outpath = tmp;
int fd = mkstemp(tmp);
if( fd == -1 ){
perror("mkstemp");
return 1;
}
if( (out = fdopen(fd, "w")) == NULL ){
perror(tmp);
return 1;
}
}
int c;
while( (c = fgetc(in)) != EOF ){
if( c == c1 ){
c = c2;
}
if( fputc(c, out) == EOF ){
perror(outpath);
return 1;
}
}
if( argc > 3 ){
if( fclose(out) ){
perror(outpath);
return 1;
}
if( rename(outpath, path) ){
perror(path);
return 1;
}
}
return 0;
}
String replace
Just for completeness, here is a bit of code to replace a word in a file! This will replace a single character, so of course it answers the question and shows some useful examples.
This is also my first and only non-trivial golden program, written in May 1994! Although you can certainly find fault with it, it worked as intended and my co-workers and I used it many different ways for sysadmin-related tasks. Compiled on MS C/C++
#include <stdio.h>
#include <string.h>
#define err(e) {_fcloseall(); fprintf(stderr, \
"USAGE: chg source dest oldstr newstr\n%s\n",e); exit(1);}
main (int argc,char *argv[])
{
FILE *in,*out;
char buffer[200];
char *old,*new;
int i,j,k;
if (argc!=5)
err("invalid # of parameters");
if ((in=fopen(argv[1],"r"))==NULL)
err("Can't open source");
if ((out=fopen(argv[2],"w"))==NULL)
err("Can't open dest");
old=argv[3];
new=argv[4];
if (*old=='"')
old++;
if (*new=='"')
new++;
if (i=strlen(old) && old[i-1]=='"')
old[i-1]=0;
if (i=strlen(new) && new[i-1]=='"')
new[i-1]=0;
if (!*old)
err("Can't search for nothing!");
if (!*new)
err("Can't replace nothing!");
j=0;
while (!feof(in))
{
if ((buffer[j]=fgetc(in))==EOF)
break;
buffer[j+1]=0;
j++;
if (!old[j-1])
{
fprintf(out,new);
fputc(buffer[j-1],out);
j=0;
}
else if (_strnicmp(buffer,old,j))
{
fprintf(out,buffer);
j=0;
}
else if (j>195)
err("Internal error, buffer filled past 195");
}
}

trying to store a text file into an array

i am trying to read from a text file and store it into an array character by character, ive tested it out by trying to print or check the ii count but it doesn't seem to be storing, any help would be muchly appreciated
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
char ch = '\0';
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
free(file);
return file;
}
I have commented out the line containing the code to free the character array before returning, which was basically making the pointer invalid. I have also changed the type of the variable "ch" to int as fgetc() returns integer.
#include <stdio.h>
#include <stdlib.h>
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
int ch; //changed to int from char.
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
// printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
//free(file); //commented this line out
return file;
}
int main()
{
char *filename = "sample.txt";
char *file_arr = readFile(filename);
printf("%s \n",file_arr);
return 0;
}

to upper case every words in file in C

can you tell me what adjustments i can do for my code, or any simplifications? What shouldn't
i repeat, what should i change ? This code converts every word to upper case, if you find some problems,pls write in order to fix it))
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(){
FILE * fPtr, *fPtr1;
int c; /*to store characters*/
char filename[20];
char filename2[20] = "temp.txt";
printf("Enter name of file: ");
scanf("%19s%*c",filename);
fPtr = fopen(filename, "r");
fPtr1 = fopen(filename2, "w");
c = fgetc(fPtr);
while(c!=EOF){
if(c!='\n'){
if(islower(c)){
fputc(c-32,fPtr1);
}else{
fputc(c,fPtr1);
}
}else{
fputc(c,fPtr1);
}
c = fgetc(fPtr);
}
fclose(fPtr);
fclose(fPtr1);
remove(filename);
rename(filename2,filename);
fPtr = fopen(filename, "r");
c = fgetc(fPtr);
while(c!=EOF){
printf("%c",c);
c = fgetc(fPtr);
}
fclose(fPtr);
}
This program does what you say it does. But I recommend some changes that your future self will appreciate.
First, always initialize your variables; this habit will help to prevent odd bugs in your future code. Set ints to a value out of your expected range (e.g. maybe -1 in this case); set pointers to NULL; set char arrays to { '\0' } or to "\0".
Next, check your file pointers (fPtr, fPtr1) for NULL after fopen.
Finally, specific to this code, your check for new-line is unnecessary; islower will return 0 if the parameter is not a lowercase alphabetic character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 20
char *mygets(char *s, size_t sz) {
int ch;
size_t i = 0;
while((ch = getchar()) != '\n' && i < sz)
s[i++] = ch;
s[i] = '\0';
return s;
}
int main(void) {
FILE *fPtr;
char filename[MAX+1];
int c, i;
printf("Enter name of file: ");
mygets(filename, MAX+1);
if(!strstr(filename, ".txt"))
strcat(filename, ".txt");
if((fPtr = fopen(filename, "r+")) == NULL) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
i = 0;
while((c = fgetc(fPtr)) != EOF) {
fseek(fPtr, i, SEEK_SET);
fputc(toupper(c), fPtr);
i++;
}
rewind(fPtr);
while((c = fgetc(fPtr)) != EOF)
putchar(c);
fclose(fPtr);
return 0;
}

How to split a text file into multiple parts in c

What i need to do, is to take a file of n lines, and for every x lines, create a new file with the lines of the original file. An example would be this:
Original File:
stefano
angela
giuseppe
lucrezia
In this case, if x == 2, 3 file would be created, in order:
First file:
stefano
angela
Second FIle:
giuseppe
lucrezia
Third File:
lorenzo
What i've done so far is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * filename = malloc(sizeof(char)*64);
char * ext = ".txt";
char number[2];
for(int i = ix; i < *mem; i++)
{
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && (ix*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
I'm stack with segmentation error, i couldn't find the bug doing
gdb myprogram
run
bt
I really appreciate any help.
EDIT:
I've changed some things and now it works, but it creates an additional file that contains strange characters. I need to still adjust some things:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * ext = ".txt";
for(int i = ix; i < *mem; i++)
{
char * filename = malloc(sizeof(char)*64);
char * number = malloc(sizeof(char)*64);
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
free(number);
free(filename);
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && ((ix-1)*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
There are a few problems in your code. But first I think you need to fix the most important thing
int step = lines/N;
Here step is 0 if your input file has less than N lines of text. This is because lines and N both are integer and integer division is rounding down.
I won't fix your code, but I'll help you with it. Some changes I
suggest:
Instead of getlines, use getline(3) from the standard
library.
fseek(fp, 0 , SEEK_SET) is pointless.
In char * filename = malloc(sizeof(char)*64), note that
both arguments to malloc are constant, and the size is arbitrary.
These days, it's safe to allocate filename buffers statically,
either on the stack or with static: char filename[PATH_MAX].
You'll want to use limits.h to get that constant.
Similarly you have no need to dynamically allocate your FILE
pointers.
Instead of
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
use sprintf(filename, "temp%d%s", i+1, ext)
get familiar with err(3) and friends, for your own convenience.
Finally, your recursive Split is -- how shall we say it? -- a nightmare. Your whole program
should be something like:
open input
while getline input
if nlines % N == 0
create output filename with 1 + n/N
open output
write output
nlines++

How to read a text file 3 characters at a time?

I'm learning to program in C, and right now my homework is like this. I am supposed to be able to take a text file with words/letters and my program should print the ascii codes+1 of the letters it gets. It's "encoding" it. So for example the letter "A" would be printed as 066. So my problem is the program needs to also be able to decode those ascii codes back to letters, but I don't know how to get my program to read 3 numbers at once. I used
c = fgetc(pF);
while (c != EOF) {
fprintf(pF2,"%03i",c+1);
c = fgetc(pF);
to read the file one character at a time. Should I use something similar to get the 3 numbers I need, or would it be something completely different?
#include "stdio.h"
#include "stdlib.h"
int encode(){
char * fName = "testR.txt";
char * fName2="testW.txt";
FILE * pF;
FILE * pF2;
char c, cArray[500];
int i=0;
pF = fopen(fName, "r");
if ( pF == NULL ) {
printf("Error: The specified file could not be opened.\n");
return -1;
}
pF2 = fopen(fName2, "w");
c = fgetc(pF);
while (c != EOF) {
fprintf(pF2,"%03i",c+1);
c = fgetc(pF);
}
fclose(pF);
fclose(pF2);
return;
}
char decode(){
char * fName = "testW.txt";
char * fName2="testW2.txt";
char * buf;
FILE * pF;
FILE * pF2;
char cArray[500];
char buffer[4];
buffer[3] = '\0';
pF = fopen(fName, "r");
if ( pF == NULL ) {
printf("Error: The specified file could not be opened.\n");
return -1;
}
pF2 = fopen(fName2, "w");
while (fread(buffer, 3, 1, stdin)){
putchar((atoi(buffer)-1) & 0xFF);
}
fclose(pF);
fclose(pF2);
}
int main (int argc, char *argv[]){
char c;
if ( argc != 2 ) {
printf("Incorrect number of arguments.\n");
exit(-1);
}
if (strcmp(argv[1], "-e") == 0){
encode();
}
if (strcmp(argv[1], "-d") == 0){
decode();
}
return 0;
}
I am aware that my code is a mess and there are probably things that shouldn't be there from all the changes I've been trying to make =[
Encoding:
int c;
while ((c = getchar()) != EOF)
printf("%.3d", (c+1)&0xFF);
Decoding:
char buffer[4];
buffer[3] = '\0';
while (fread(buffer, 3, 1, stdin))
putchar((atoi(buffer)-1) & 0xFF);
Technically, if the output does not end with a newline when encoding, the output is not a text file. There's no error checking on the input. The fread() will return 1 when it reads a triplet of characters; otherwise, it will return 0.
Working Programs
e3.c — encryption
#include <stdio.h>
int main(void)
{
int c;
while ((c = getchar()) != EOF)
printf("%.3d", (c+1)&0xFF);
return 0;
}
d3.c — decryption
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char buffer[4];
buffer[3] = '\0';
while (fread(buffer, 3, 1, stdin))
putchar((atoi(buffer)-1) & 0xFF);
return 0;
}
Sample output
$ e3 < e3.c
036106111100109118101102033061116117101106112047105063011011106111117033110098106111041119112106101042011124011033033033033106111117033100060011011033033033033120105106109102033041041100033062033104102117100105098115041042042033034062033070080071042011033033033033033033033033113115106111117103041035038047052101035045033041100044050042039049121071071042060011033033033033115102117118115111033049060011126011011$
$
The dollar at the end of the line is the prompt.
$ e3 <e3.c | d3
#include <stdio.h>
int main(void)
{
int c;
while ((c = getchar()) != EOF)
printf("%.3d", (c+1)&0xFF);
return 0;
}
$ e3 <e3.c | d3 | diff e3.c -
$
Basic round-tripping the encoding and decoding shows that the code works.
while (fread(buf, 1, 3, pF) == 3)
{
...
}

Resources