Write in stdin from inside a program in C - c

I am trying to open a .txt file and put its contents in the standard input. I know you can do:
myapp < input.txt
but i want to use the same content several times inside the program and i think that with this method the stdin content is consumed and can not be used again.
I want to test a function that reads from stdin, just as an example of what i am trying:
void myFunction(int number)
{
// The function already writen reads from stdin using the argument.
}
void fillStdin(void)
{
FILE* myFile;
myFile = fopen("myfile.txt", "r");
// Put the content of the file in stdin
fclose(myFile);
}
int main(void)
{
int myArray[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++)
{
fillStdin();
myFunction(myArray[i]);
}
return 0;
}

No need to modify your code. Just execute your program as this (assuming you are using Unix):
while true; do cat input.txt; done | myapp
This will feed input.txt to your stdin over and over again. Take into account that you will need to figure out when you have reached the end of each recurrence, as stdin will never EOF this way.

you can easily write into stdin like so:
char *buffer = malloc(bufsize * sizeof(char));
... //get file contents etc.
write(STDIN_FILENO, buffer, bufsize); //the important part.
you'll need to include unistd.h and I don't think it's portable.

Here is a simple example of how you can read stdin into a storage buffer, and into a file.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define MAXLINELENGTH 4096
FILE *fin;
char fileName[] = "temp.txt";
void processLine(char *line)
{
fin = fopen(fileName, "a");
fputs(line, stdout);
fputs(line, fin);
fclose(fin);
return;
}
int main()
{
char line[1024];
char input[MAXLINELENGTH];
printf("enter continuous text, and ~ when finished\n");
while (fgets(line, 1024, stdin) != NULL)
{
processLine(line);
if(strstr(line, "~")) //enter a "~" to exit program
return 0;
}
return 0;
}
Once you have the file, you can read from it using fopen() and fgets(), then write it back out to stdout.

Related

Why does (while .. getchar()) does not write to my file, in C?

I need to write a program that asks the user to enter strings, each string ends when the user presses 'Enter'.
The program needs to receive the file name as a parameter, the file should be opened and closed for each operation and for every string entered, the program should append the string to the end of the file (on a new line).
This is my code so far:
int is_file_exists(char *file_name)
{
FILE *file;
if ((file = fopen(file_name,"r"))!=NULL)
{
/* file exists */
fclose(file);
return 1;
}
else
{
//File not found, no memory leak since 'file' == NULL
//fclose(file) would cause an error
return 0;
}
}
int main(int argc, char **argv)
{
char c;
FILE *file;
if (argc >= 2)
{
if (is_file_exists(argv[1]))
{
file = fopen(argv[1], "w");
}
else
{
return 0;
}
}
else
{
file = fopen("file.txt", "w");
}
while ((c = getchar()) != EOF)
{
putc(c, file);
}
return 0;
}
So far the code compiles and file is being created, but nothing is being written inside of it.
Edit: I also need some function pointers, see my comments on selected answer
I think one of the problem was that you were opening and closing a file, and then reopening it subsequently. It is better to just leave it open using a pointer while simultaneously testing that there were no issue to open the file. Another problem was that you were writing in the file, don't you prefer to append text to it? Well it's your decision. As for the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // exit
typedef struct mystruct {
char *exit_word;
void (*exit_fptr)(int); // man exit
int (*strcmp_fptr)(const char *, const char*); // man strcmp
} t_mystruct;
int is_file_exists(char *filename, FILE **file)
{
return (*file = fopen(filename,"a")) > 0;
}
#define BUFF_SIZE 1024
int main(int argc, char **argv)
{
char c;
FILE *file;
t_mystruct s = {.exit_word = "-exit", .exit_fptr = &exit, .strcmp_fptr = &strcmp};
if (argc >= 2) {
if (!(is_file_exists(argv[1], &file)))
return 0;
}
else
file = fopen("file.txt", "a"); // open the file in append mode
char buffer[BUFF_SIZE];
while (42) {
int i = 0;
memset(buffer, 0, BUFF_SIZE);
while ((c = getchar()) != '\n')
buffer[i++] = c;
if (!s.strcmp_fptr(buffer,s.exit_word)) {// exit if user type exit, allow you to fclose the file
fclose(file);
s.exit_fptr(EXIT_SUCCESS); // better to use the define
}
buffer[i] = '\n';
fputs(buffer, file);
}
fclose(file);
return 0;
}
your code can work
remember to press Ctrl+d when finished input. the file will have the content your expected
your code wait for EOF to quit the loop. Ctrl+d is a way to input EOF, or else the program never ends.
putc will write to cache at first, then write to disk. this an optimization mechanism of File System. you can choose to avoid this by DirectIO when open file.
when program terminate normally, file will be closed automatically, then data in cache will be copy to disk;
but when program terminated abnormally, data in cache might be lost.
file should be closed
fclose is needed.
open and close should be organized in pair just as malloc and free.

I want to copy my in file on to my out file.

In this code I opened my files in my open_file function. Then the process_file function needs to copy the text from my in file and Copy it to an out file. Right now it produces a new file but it is blank. It does not give me any error messages. I do not know what is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 100
FILE* open_file(char prompt[], char mode[]);
FILE* process_file(FILE* in, FILE* out);
int main(int argc, const char * argv[]) {
FILE* in = NULL;
FILE* out = NULL;
printf("MAD-LIBS Text Processor\n");
printf("The Program will open a mad-libs file, ask you to fill various words, and produce a funny story.\n");
open_file("Enter mad-lib file name:\n", "r");
open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
fclose(in);
fclose(out);
return 0;
}
/* open_file = prompts user for file name & and attempts to open it, if it fails it prompts the user again. */
FILE* open_file(char prompt [], char mode[]) {
char filename[255];
FILE* in;
do {
printf("%s", prompt);
scanf("%s", filename);
in = fopen(filename, mode);
if (in == NULL) {
printf("Unable to open file: %s. Try Again!\n", filename);
}
} while(in == NULL);
return in;
}
/* process_file = processes entire input file and writes it to output file */
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
char NewContent[MAX_LEN];
//gets whats in file in
while(fgets(content, content[MAX_LEN], in) != NULL) {
fputs (content, stdout);
strcat(NewContent, content);
}
// copies it
while (fgets(content, content[MAX_LEN], in) != NULL) {
fprintf(out, "%s", content);
}
printf("Successfully copied file\n");
return in;
}
You never assign the FILE* from open_file function to your variable, so it never gets processed.
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
You are not storing the FILE pointers that open_file is returning, so in
and out remain uninitialized.
You have to do:
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
Also your process_file is wrong. NewContent is not initialized, when you do
strcat(NewContent, content);
this yields undefined behaviour. Declare NewContent like this:
char NewContent[MAX_LEN] = { 0 };
so that it is properly \0-terminated.
Also depending on the size of the file you are copying, MAX_LEN might not be
long enough to hold the whole file. In that case you would overflow the buffer.
It would be better not to use NewContent in the first place and write to out
in the same reading loop:
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
//gets whats in file in
while(fgets(content, MAX_LEN, in) != NULL) { //<- your fgets was wrong
fputs (content, stdout);
fprintf(out, "%s", content); // or fputs(content, out);
}
printf("Successfully copied file\n");
return in;
}
And you were calling fgets incorrectly (look at my corrected code)
Also bear in mind, that you did have 2 loop doing while(fgets(...) != NULL.
Well, the first loop ends, that's because fgets returns NULL, most likely
because the whole file was read or there was an I/O error. In either case
subsequent calls of fgets will return NULL as well, so your second loop
would not even be executed at all.

How do I read a file line by line in C from the terminal?

I have read that I can use fopen to read a file line by line, but I want to access the file from the terminal as such.
This is what I have tried:
$ ./myprogram < input.txt > output.txt
I'm not sure if there's a way to do it with scanf or another way?
Here, if you think about what you are doing, you are simply reading continually from stdin and writing the same bytes to stdout until you receive an EOF. While you can use a character oriented approach (e.g. getchar), a read with a fixed length buffer will dramatically cut down the number of reads and writes you have.
Simply declare a buffer of comfortable size, 1024 (or use the default BUFSIZ provided, generally 8192 on Linux and 512 on windoze). Then repeatedly call fgets reading a buffers worth of characters at a time and writing them back to stdout with fputs. That's about as simple as it gets.
#include <stdio.h>
#define BUFSZ 1024
int main (void) {
char buf[BUFSZ] = "";
while (fgets (buf, BUFSZ, stdin))
fputs (buf, stdout);
return 0;
}
Ideally, you would want a buffer size just longer than the longest line, although it really doesn't matter what size it is. You can read each line all at once, or in multiple calls to fgets. The only difference is the number of function calls made.
#include <stdio.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
char *line = (char *)malloc(BUFSIZE);
if (!line)
{
printf("malloc buffer failed...\n");
return 1;
}
memset(line, 0, sizeof(line));
FILE *fp;
FILE *writefp;
int c;
int count = 0;
int count_buf = BUFSIZE;
char scanf_answer;
if (argc != 3)
{
printf("./myprogram <input.txt> output.txt\n");
return 1;
}
fp = fopen(argv[1], "r");
for (;;)
{
c = getc(fp);
if (c == '\n')
{
printf("%s\n", line);
printf("<Did you want to write this line to [%s]?>", argv[2]);
scanf("%c", &scanf_answer);
if (scanf_answer == 'Y' || scanf_answer == 'y')
{
writefp = fopen(argv[2], "a+");
fprintf(writefp, "%s\n", line);
fclose(writefp);
}
memset(line, 0, sizeof(line));
}
else if (c == EOF)
{
printf("%s\n", line);
printf("<Did you want to write this line to [%s]?>", argv[2]);
scanf("%c", &scanf_answer);
if (scanf_answer == 'Y' || scanf_answer == 'y')
{
writefp = fopen(argv[2], "a+");
fprintf(writefp, "%s\n", line);
fclose(writefp);
}
printf("End of file\n");
break;
}
if (count >= count_buf)
{
line = realloc(line, BUFSIZE);
count_buf += BUFSIZE;
if (!line)
{
printf("realloc buffer failed...\s");
return 1;
}
count = 0;
}
sprintf(line,"%c%c", line, c);
++count;
}
fclose(fp);
return 0;
}
This code will print each line, you decide each line to write to the output.txt, and in the file end, it will print End of file
$ ./myprogram < input.txt > output.txt
The command you posted uses a shell feature called IO redirection to produce input on stdin from one file and redirect output to stdout to the other file.
To take lines as input to your program is super easy even for lines of arbitrary length if you can use POSIX getline(). Please consult the manpage (linked below) for details.
Here's an example:
#include <stdio.h>
#include <stdlib.h>
int main() {
// this is the buffer data is read to (including trailing newline)
char *buffer = 0;
// this will be set to the size of the buffer
size_t buffer_size = 0;
// this will be set to the number of bytes read
ssize_t bytes_read;
while ((bytes_read = getline(&buffer, &buffer_size, stdin)) != -1) {
// do something with line
printf("%s", buffer);
// the same buffer will be reused in the next loop iteration
}
// free buffer eventually
free(buffer);
return 0;
}
Possible output:
$ gcc test.c && ./a.out < test.c
#include <stdio.h>
#include <stdlib.h>
int main() {
[...]
Note that scanf() is for taking formatted input, which reading lines is not. I suggest you get to learn more about the different approaches to IO (on streams) here:
https://www.gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html#I_002fO-on-Streams
For reference:
http://man7.org/linux/man-pages/man3/getline.3.html

C Programming Read file and store it as a string [duplicate]

This question already has answers here:
Reading the whole text file into a char array in C
(5 answers)
Closed 8 years ago.
I wrote c code which input value for my program comes from here :
char *input[] = {"This input string value !!!", NULL};
But how can I read this value from the file (e.g. input.txt)? Is it possible to get the file content like a string?
Thanks a lot!
If you want to read a file line-by-line, the easiest way to go is using getline. Read the man page for a detailed description and a good code example.
getline will do all the low-lvel plumbing work of allocating buffers, copying data and scanning for newline characters, etc for you. Keep in mind that this is only possible since getline uses dynamically allocated memory that you'll need to free again.
On recent Posix compliant systems you could use getline(3), something like
FILE *fil = fopen("somefile.txt", "r");
if (!fil) {perror("somefile.txt"); exit(EXIT_FAILURE); };
char*linbuf = NULL;
size_t siz = 0;
ssize_t linlen = 0;
while ((linlen=getline(&linbuf, &siz, fil))>0) {
// linbuf contains the current line
// linlen is the length of the current line
do_something_with(linbuf, linlen);
};
fclose(fil);
free(linbuf), linbuf=NULL;
linlen = 0, siz = 0;
You can use fgets() like this:
#include <stdio.h>
int main(void)
{
char buffer[100];
FILE *file = fopen("input.txt", "r");
// Checks if the file was opened successfully
if (file == NULL)
{
fputs("Failed to open the file\n", stderr);
return -1;
}
// fgets here reads an entire line or 99 characters (+1 for \0) at a time, whichever comes first
while (fgets(buffer, sizeof(buffer), file) != NULL)
{
printf("Line read = %s\n", buffer);
}
fclose(file);
}
You can also use fgetc() like this:
#include <stdio.h>
int main(void)
{
int ch;
FILE *file = fopen("input.txt", "r");
// Checks if the file was opened successfully
if (file == NULL)
{
fputs("Failed to open the file\n", stderr);
return -1;
}
// fgetc reads each character one by one until the end of the file
while ((ch = fgetc(file)) != EOF)
{
printf("Character read = %c\n", ch);
}
fclose(file);
}

How can i select the last line of a text file using C

I am trying to find out a way to select the last line of a text file using C (not c++ or c#, just C) and I am having a difficult time finding a way to do this, if anyone could assist me with this problem I would be very grateful, thanks! (btw for a good example of what i am trying to do, this would be similar what to tail -n 1 would be doing in bash)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(int argc, char *argv[])
{
FILE *fd; // File pointer
char filename[] = "./Makefile"; // file to read
char buff[1024];
if ((fd = fopen(filename, "r")) != NULL) // open file
{
fseek(fd, 0, SEEK_SET); // make sure start from 0
while(!feof(fd))
{
memset(buff, 0x00, 1024); // clean buffer
fscanf(fd, "%[^\n]\n", buff); // read file *prefer using fscanf
}
printf("Last Line :: %s\n", buff);
}
}
I'm using Linux.
CMIIW
No direct way, but my preferred method is:
Go to the end of the file
Read last X bytes
If they contain '\n' - you got your line - read from that offset to the end of the file
Read X bytes before them
back to 3 until match found
If reached the beginning of the file - the whole file is the last line
E.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef max
#define max(a, b) ((a)>(b))? (a) : (b)
#endif
long GetFileSize(FILE *fp){
long fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);//reset stream position!!
return fsize;
}
char *lastline(char *filepath){
FILE *fp;
char buff[4096+1];
int size,i;
long fsize;
if(NULL==(fp=fopen(filepath, "r"))){
perror("file cannot open at lastline");
return NULL;
}
fsize= -1L*GetFileSize(fp);
if(size=fseek(fp, max(fsize, -4096L), SEEK_END)){
perror("cannot seek");
exit(1);
}
size=fread(buff, sizeof(char), 4096, fp);
fclose(fp);
buff[size] = '\0';
i=size-1;
if(buff[i]=='\n'){
buff[i] = '\0';
}
while(i >=0 && buff[i] != '\n')
--i;
++i;
return strdup(&buff[i]);
}
int main(void){
char *last;
last = lastline("data.txt");
printf("\"%s\"\n", last);
free(last);
return 0;
}
If you are using *nix operating system, you can use the command 'last'. See 'last' man page for details.
If you want integrate the functionality inside another program, you can use 'system' call to execute 'last' and get it's result.
A simple and inefficient way to do it is to read each line into a buffer.
When the last read gives you EOF, you have the last line in the buffer.
Binyamin Sharet's suggestion is more efficient, but just a bit harder to implement.

Resources