I am writing a very simple editor. I have it so that the program reads from stdin and then prints to stdout right now (see code below). I want a program that will take in a file, and then depending on the command either print or append more text to the file. I am still confused how to do this after reading related questions. Do I use both scanf to read the file and then printf to print into the same file? Any clarification is much appreciated.
#include <stdio.h>
#define MAX_LINES 10
char text[MAX_LINES][MAX_LINES];
int main(void){
FILE *infile;
infile = fopen("file.txt", "w");
//check for file
if(infile==NULL){
puts("Error--no file found");
}
int count, x, y;
printf("Enter to quit the program.\n");
for(count=1; count<MAX_LINES+1; count++){
printf("%d: ", count);
fgets(text[count], MAX_LINES, stdin);
}
for(x=0; x<count; x++){
for(y=0;text[x][y];y++){
putchar(text[x][y]);}
putchar('\n');
}
fclose(infile);
return 0;
//end program
}
Your program does not "read from stdin", it reads from a named file, but, does not write to that file.
And here is another confusion
char text[MAX_LINES][MAX_LINES];
This would be better as
#define MAX_LINES 10
#define MAX_LENGTH 1000
...
char text[MAX_LINES][MAX_LENGTH];
Next, look at this loop
for(count=1; count<MAX_LINES+1; count++)
This will ignore the 0th element of the array and go out of bounds with the last. It should be
for(count=0; count<MAX_LINES; count++)
This is for stdin, but if the file is an opened disk file, say infile you should check if the read hits the end of the file
fgets(text[count], MAX_LINES, infile);
and replace with with
if (fgets(text[count], MAX_LENGTH, infile) == NULL)
break;
Your commented question Is there a way to both read from infile and add the text to infile? Yes but it's unviable, as #JonathanLeffler wrote "prepare a new file first".
Related
This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 2 months ago.
I am currently learning how to write to txt file in c. I encountered a problem where the first column of text won't output the string it has been given.
#include <stdio.h>
#include <string.h>
int main() {
FILE * fptr;
//open file
fptr = fopen("test.txt", "a");
//entering how many lines will be used
int columns;
scanf("%d", &columns);
//loop for writing in lines
for (int i = 0; i < columns; i++) {
char temp_text[10001];
fgets (temp_text, 10000, stdin);
//to remove the \n caused by fgets
temp_text[strlen(temp_text) - 1] = '\0';
//fprintf is compatible with placeholders
fprintf (fptr, "data %d: %s\n", i, temp_text);
}
//closing file
fclose (fptr);
return 0;
}
The inputs are:
5
qw
er
ty
ui
I expected it to ask for n (in this case 5) time/s, instead it always asks for one less. The txt file shows:
data 0:
data 1: qw
data 2: er
data 3: ty
data 4: ui
A shown, it always skips putting the given string on the first line as well.
Thank you in advance.
In the code posted by the OP, immediately after the user enters the value for columns, the program enters the for loop and tries to read from stdin, which happens to be just a LF (line-feed). For the OP's code to work, the user would have to enter, say, 5 blabla instead of just 5, when requested for the number of columns, so that fgets has something to read after scanf has consumed the digits for columns.
As the problem is related to the way the code handles user's input, I altered the original code so that it doesn't open/write to a file and uses scanf instead of fgets in the loop, and I tested it on https://www.programiz.com/c-programming/online-compiler/. The following version works as expected:
#include <stdio.h>
#include <string.h>
int main() {
//FILE * fptr;
//open file
//fptr = fopen("test.txt", "a");
//entering how many lines will be used
int columns;
printf("Enter n of cols: ");
scanf("%d", &columns);
//loop for writing in lines
for (int i = 0; i < columns; i++) {
char temp_text[100];
scanf ("%s", &temp_text);
//to remove the \n caused by fgets
//temp_text[strlen(temp_text) - 1] = '\0';
//fprintf is compatible with placeholders
printf ("entered for %d: %s\n", i, temp_text);
}
//closing file
//fclose (fptr);
return 0;
}
I would like to copy a huge txt file and 'shrink' it. this is my code, but it seems it's still takes a lot of time reading the file. is there a way to read from a specific line number to EOF? for instance, the first 1 million lines are not useful to me, how to read from line 1 million. or anyway to read from EOF?
include<stdio.h>
include<stdlib.h>
void main() {
FILE *fp1, *fp2;
char ch;
int i = 1;
int n = 0;
int k;
fp1 = fopen("co.data", "r"); /* open a file to read*/
fp2 = fopen("Output.txt", "w"); /* open a file to write*/
printf("please enter how many lines do not need to be copied\n");
scanf ("%d", &k);
while (1) {
ch = fgetc(fp1); /* a loop to read/copy the file*/
if (ch == '\n') /* record the number of lines*/
i++;
if (ch == EOF)
break;
else if (i>k)
putc(ch, fp2);
}
printf("File copied Successfully!\n");
printf("number of lines read is %d\n",i-1);
printf("number of lines copied is %d\n",i-1-k);
fclose(fp1);
fclose(fp2);
}
There are two potential answers to your question, depending on if your file has known line lengths or not.
is there a way to read from a specific line number to EOF
In a file with line lengths are completely arbitrary (variable), no.
For example, if line 1 is 10 characters, and line 2 is 20 characters, then there is no way to calculate where line 3 is going to start without iterating through lines 1 and 2.
Operating systems aren't magic; if this kind of functionality was supported, they'd have to iterate through the file first as well. Either way, you're going to be looping through the contents.
Now, if the line lengths are guaranteed to be the same, that's a different story.
Say you have a text file like so:
AAAAAAA
BBBBBBB
CCCCCCC
Each line in the above text file is 7 characters. Assuming your line terminator is \n, each line takes up exactly 8 bytes.
In this case, you can safely fread() 8 bytes at a time and know that you're getting exactly one line. In order to jump to a particular byte in a file, you would use fseek().
Since you know the length of the lines in this scenario, you could jump to line N by simply doing
fseek(fp1, S * N, SEEK_SET);
where N is the line number (starting at 0) and S is the length of the line (as mentioned above, 8 bytes in our example file).
Note that the second solution will break if you're using a multi-byte encoding such as Unicode. Keep that in mind.
Using fgets() i made program, try it.
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp1, *fp2;
char ch,*str,*r;
int i =0;
int n = 0;
int l;
fp1 = fopen("co.data", "r");
fp2 = fopen("Output.txt", "w+");
printf("please enter how many lines do not need to be copied\n");
scanf ("%d", &l);
while (1)
{
if(r=fgets(str, 500, fp1))
{ /* a loop to read/copy the file*/
i++;
}
if (r == NULL)
break;
else if (i > l)
fputs(str, fp2);
}
printf("File copied Successfully!\n");
printf("number of lines read is %d\n",i-1);
printf("number of lines copied is %d\n",i-1-l);
fclose(fp1);
fclose(fp2);
}
I have a text file text.txt that reads (for simplicity purposes)
this is line one
this is line two
this is line three
Again for simplicity's sake, I am just trying to set the first character in each line to 'x', so my desired result would be
xhis is line one
xhis is line two
xhis is line three
So I am opening the text.txt file and trying to overwrite each line with the desired output to the same text file. In the while loop, I set the first character in each line to 'x'. I also set the variable "line" equal to one, because if its on the first line, I want to rewind to the beginning of the file in order to overwrite at the start instead of at the end of the file. Line is then incremented so it will skip the rewind for the next iteration, and should continue to overwrite the 2nd and 3rd lines. It works perfectly for the first line.
Anybody have any solutions? BTW, I have researched this extensively both on stackoverflow and other sites, and no luck. Here's my code and my output is also below:
#include <stdio.h>
#include <stdlib.h>
#define MAX 500
int main() {
char *buffer = malloc(sizeof(char) * MAX);
FILE *fp = fopen("text.txt", "r+");
int line = 1;
while (fgets(buffer, 500, fp) != NULL) {
buffer[0] = 'x';
if (line == 1) {
rewind(fp);
fprintf(fp, "%s", buffer);
}
else {
fprintf(fp, "%s", buffer);
}
line++;
}
free(buffer);
fclose(fp);
}
Output:
xhis is line one
this is line two
xhis is line two
e
x
long pos = ftell(fp);//Save the current position
while (fgets(buffer, 500, fp) != NULL) {
buffer[0] = 'x';
fseek(fp, pos, SEEK_SET);//move to beginning of line
fprintf(fp, "%s", buffer);
fflush(fp);
pos = ftell(fp);//Save the current position
}
I always suggest to use another file do this kindda solutions.
Read the line
Put x in a new file in a line and the copy the rest of the line.
Do this till you get EOF
remove the old file
rename this new file
try this out
#include<stdio.h>
#include<stdio.h>
#include<string.h>
int main()
{
char buffer[500],read[50][50];
FILE *fp=fopen("text.txt","r+");
int line =1;
while(fgets(buffer,500,fp)!=NULL){
buffer[0]='x';
printf("\n%d ",line);
puts(buffer);
strcat(read[line-1],(const char*)buffer);
line++;
}
fclose(fp);
FILE *fp1=fopen("text.txt","w");
rewind(fp1);
fprintf(fp1,"%s",read);
return 0;
}
I worked this out on windows
// file_overwrite.cpp : main project file.
// File opens and write y value to a file
// again reads same file and re-writes y value to a file
#include "stdafx.h"
using namespace System;
#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include <conio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
int x = 19530;
FILE *fp1 = fopen("D:\\Data\\BUFF.txt","w+");
if(fp1 == NULL)
printf("File not opening \n");
int y=x;
fprintf(fp1, "%d \n", y);
fclose(fp1);
printf("\n file -> open -> write y value and close");
freopen("D:\\Data\\BUFF.txt", "w", fp1);
rewind(fp1);
y=100;
fprintf(fp1, "%d \n", y);
printf("\n file -> Reopen -> rewind write y values and close");
fclose(fp1);
getch();
return 0;
}
// overwrite_file.cpp
// File opens and write y value to a file
// again reads same file and re-writes y value to a file
#include "stdafx.h"
using namespace System;
#include<stdio.h>
#include<stdio.h>
#include<string.h> //Include appropriate headers
#include <conio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
int x = 19530; // Give any value in the limit
FILE *fp1 = fopen("D:\\Data\\BUFF.txt","w+"); // open file to write
if(fp1 == NULL) // if the file pointer encounters a null, it may not open neither overwrite
printf("File not opening \n");
int y=x;
fprintf(fp1, "%d \n", y); //print y
fclose(fp1);
printf("\n file -> open -> write y value and close"); // close the file after writing the value of y
freopen("D:\\Data\\BUFF.txt", "w", fp1); //reopen and rewind file
rewind(fp1);
y=100; // this value of y given within the limits gets printed on the .exe console
fprintf(fp1, "%d \n", y);
printf("\n file -> Reopen -> rewind write y values and close"); // rewind write values and close
fclose(fp1);
getch();
return 0;
}
in the code below:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp ;
fp = fopen("out.txt", "r+");
int count = 1;
char ch ;
char userInput[5] ;
int lineNumber = 0;
while (lineNumber!= -1){
fgets(userInput, sizeof(userInput), stdin);
lineNumber = atoi(userInput);
while((ch=fgetc(fp))!=EOF)
{
if(ch=='\n') //counts number of lines
count++;
if(count == lineNumber)
{
fprintf(fp, "writed %d\n", count);
fseek(fp, 0, SEEK_SET);
}
}
}
return 0;
}
I want to write a string in the line which the user gives me,i store the user answer in userInputand then convert it to the int and store it in lineNumber.
when i try to write fore example in line 90 (my file has 100 lines) two error i get:
1.the file reduce to a 91-line file (instate of remain 100 lines)
2.although i seek to first of file,no more lines written in the next loops and user inputs.
Reading a file (to count its lines) and then turning around and writing to it is tricky. Among other things, you have to do something like an fseek between the reading and the writing. So try interchanging the order of the fseek and fprintf calls:
fseek(fp, 0, SEEK_SET);
fprintf(fp, "writed %d\n", count);
Also, be aware that unless the new text you're writing ("writed ###") is exactly the same length as whatever line used to be there, the line structure of the remainder of the file is likely to get garbled.
See also this question in the C FAQ list.
I have recently learnt about using I/O files in C, and one of my book exercises asks me to read lines of pairs of number and add them, then print them to an output file.
What I mean is:
If the input file looks like:
12 13
24 26
23 13
the output file will be:
25
50
36
I have tried reading it as a string using:
fscanf(in, "%s", &string); //in is the input file pointer
but it doesn't work (causes a seg. fault)
My problem is that I am unable to take in the lines of pairs of numbers using the fscanf function, as I do not know how many lines there are in the input file.
Thus, my question is: How do I read an input file containing an amount of lines if I do not know how many lines there are? Can I read it as a string?
Thank you in advanced.
Michael
Here's some working code:
#include <stdio.h>
#include <conio.h>
main()
{
int a,b;
FILE *fp = fopen("filename.txt", "r"); //open file for reading
FILE *f = fopen("file.txt", "w"); //open file for writing
while (!feof (fp)) //reading file until end of file
{
fscanf (fp, "%d", &a);
fscanf (fp, "%d", &b);
int sum = a + b;
fprintf(f, "%d\n", sum); //writing summation to a file
}
fclose(f); //close files
fclose(fp);
return 0;
}
Just create filename.txt and write numbers in it. And create blank file.txt.