I need to open a file located on Desktop(Linux). If i write the location as a string inside the fopen() function it works, but if i pass it as a variable, it doesn't work. Here is my code :
fp = fopen(readPathToFile, "r");
if (!fp){
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
If i write it like this, it shows me the content of file :
fp = fopen("home/user/Desktop/test.txt", "r");
if (!fp){
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
The child process opens the file. Here is my full code
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
int main ()
{
pid_t pid;
int mypipefd[2];
id_t child_pid;
char line[100];
char *pathToFile[100];
FILE *fp;
char buff[255];
/* create the pipe */
if (pipe(mypipefd) == -1) {
fprintf(stderr,"Pipe failed");
return 1;
}
child_pid = fork () ;
if (child_pid > 0) {
printf("Introduceti locatia catre fisier:");
fgets(pathToFile, 100, stdin);
close(mypipefd[READ]);
write(mypipefd[WRITE], &pathToFile, sizeof(pathToFile));
close(mypipefd[WRITE]);
printf("parent: write value : %s",pathToFile);
}
else if (child_pid < 0) {
fprintf(stderr, "Fork failed");
return 1;
}
else{
char *readPathToFile[100];
close(mypipefd[WRITE]);
read(mypipefd[READ], &readPathToFile, sizeof(readPathToFile));
close(mypipefd[READ]);
printf("child: read value : %s",readPathToFile);
fp = fopen(readPathToFile, "r");
if (!fp)
{
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
}
return 0;
}
Your compiler did not warn you about the type mismatch in
char *pathToFile[100];
fgets(pathToFile, 100, stdin);
(array of 100 pointers-to-char versus array of 100 chars)? Did you turn warnings off?
Also note that fgets retains the newline. Your file name probably does not end with a newline. You should replace it with a NUL (zero) byte.
Typically you don't need a debugger to track these down. A little bit of printf debugging can do wonders. :-)
Okay, so this is the root of your problem:
char *pathToFile[100];
This declares pathToFile as a 100-element array of pointers to char, not a 100-element array of char. The first thing you need to do is change that declaration to
char pathToFile[100];
Secondly, fgets will save the trailing newline from your input to the target buffer if there's room, so you'll need to remove that newline from the input:
char *newline = strchr( pathToFile, '\n' );
if ( newline )
*newline = 0;
Related
I am unable to save a char array using fprint() and i cannot figure out why. The below codes compliles correctly but saves nothing to file. Please advise.
static char bitSpecial[100];
int main(int argc, char *argv[]) {
FILE *fp
fp = fopen(thefilename, "w+");
if (fp == NULL) {
printf("I couldn't open file for writing.\n");
exit(0);
}
/* populate bitSpecial one character at the time and verify array is full */
fprintf(fp,"%s", bitSpecial);
if (fclose(fp) != 0) puts("Unable to close the file");
return
}
It'll be easier to identify the problem with the full code. I tried the following snippet and it worked:
#include <stdio.h>
#include <string.h> // for strerror
#include <errno.h> // for errno
static char bitSpecial[100];
int main(int argc, char *argv[])
{
char * thefilename = "test";
FILE *fp;
fp = fopen(thefilename, "w+");
if (fp == NULL) {
printf("I couldn't open file for writing.\n");
return 1;
}
/* populate bitSpecial one character at the time and verify array is full */
bitSpecial[0] = 'a';
bitSpecial[1] = '\n';
bitSpecial[2] = '\0'; // terminator
if (fprintf(fp,"%s", bitSpecial) < 0)
printf("[+] fprintf failed with '%s'\n", strerror(errno));
if (fclose(fp) != 0)
puts("Unable to close the file");
return 0;
}
Verify that you put a null terminator (\0) at the end of bitSpecial, and check the return value of fprintf.
I tried to write basic program in C which copy data from file to another with given source path, destination path and buffer size as input.
my problem is the destination file filled with junk or something because its way larger than the source (get bigger depending on buffer size) and can't be open.
How do i read and write just the bytes in the source?
i'm working in linux, and this is the actually copying part:
char buffer[buffer_size];
int readable=1;
int writeable;
while(readable != 0){
readable = read(sourcef, buffer, buffer_size);
if(readable == -1){
close(sourcef);
close(destf);
exit_with_usage("Could not read.");
}
writeable = write(destf, buffer, buffer_size);
if(writeable == -1){
close(sourcef);
close(destf);
exit_with_usage("Could not write.");
}
}
writeable = write(destf, buffer, buffer_size);
must be
writeable = write(destf, buffer, readable);
Currently you do not write the number of characters you read but all the buffer, so the output file is too large
You also manage wrongly the end of the input file
The return value of read is :
On success, the number of bytes read is returned (zero indicates end of file)
On error, -1 is returned
A proposal :
/* you already check input and output file was open with success */
char buffer[buffer_size];
for(;;){
ssize_t readable = read(sourcef, buffer, buffer_size);
if(readable <= 0){
close(sourcef);
close(destf);
if (readable != 0)
/* not EOF */
exit_with_usage("Could not read.");
/* EOF */
break;
}
if (write(destf, buffer, n) != n) {
close(sourcef);
close(destf);
exit_with_usage("Could not write.");
}
}
I suppose exit_with_usage calls exit() so does not return
Note in theory write may write less than the expected number of characters without being an error, and the write has to be done in a loop, but in that case it is useless to manage that
read function returns how many bytes were read to buffer(which has buffer_size). Its not always the case actual bytes read has same value as buffer size(consider scenario if there are not enough bytes left in source file to fully fill your buffer). So you should write to destination file not buffer_size(third argument of the write function), but how many bytes have you read - that is readable variable in your code
You should exit when readable returns an error.So
while(readable != 0){
should be
while(readable != -1){
So that loop could be terminataed when an readfile is exhausted.
You see currently after the whole readfile has been read, calling read fails but write is being called repeatedly since execution has no exit path for failure on read. Also write should only write the number of bytes read. So the code would look like this:
char buffer[buffer_size];
int readable=1;
int writeable;
while(readable != -1){
readable = read(sourcef, buffer, buffer_size);
if(readable == -1){
close(sourcef);
close(destf);
exit_with_usage("Could not read.");
}
writeable = write(destf, buffer, readable);
if(writeable == -1){
close(sourcef);
close(destf);
exit_with_usage("Could not write.");
}
}
Simple code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // For system calls write, read e close
#include <fcntl.h>
#define BUFFER_SIZE 4096
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage %s Src_file Dest_file\n", argv[0]);
exit(1);
}
unsigned char buffer[BUFFER_SIZE] = {0};
ssize_t ReadByte = 0;
int src_fd, dst_fd;
// open file in read mode
if ((src_fd = open(argv[1], O_RDONLY)) == -1) {
printf("Failed to open input file %s\n", argv[1]);
exit(1);
}
// open file in write mode and already exists to overwrite
if ((dst_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 644)) == -1) {
printf("Failed to create output file %s\n", argv[2]);
exit(1);
}
// loop
while (1) {
// read buffer
ReadByte = read(src_fd, buffer, sizeof(buffer));
// error with reading
if (ReadByte == -1) {
printf("Encountered an error\n");
break;
} else if (ReadByte == 0) {
// file end exit loop
printf("File copying successful.\n");
break;
}
// error with writing
if (write(dst_fd, buffer, ReadByte) == -1) {
printf("Failed to copying file\n");
break;
}
}
// Close file
close(src_fd);
close(dst_fd);
exit(0);
}
Run
./program src_file dest_file
I'm writing code that's supposed to verify that a .txt file is a certain format.
I wrote my code as I saw in a tutorial and in the website
and for some reason my program doesn't even print my file.
Can you tell me what I'm doing wrong?
The code will do something far more complex, but I'm still trying to work on my basics.
Here's my code so far:
int main(int argc, char *argv[]) {
/* argv[0] = name of my running file
* argv[1] = the first file that i receive
*/
define MAXBUFLEN 4096
char source[MAXBUFLEN + 1];
int badReturnValue = 1;
char *error = "Error! trying to open the file ";
if (argc != 2) {
printf("please supply a file \n");
return badReturnValue;
}
char *fileName = argv[1];
FILE *fp = fopen(argv[1], "r"); /* "r" = open for reading */
if (fp != NULL) {
size_t newLen = fread(&source, sizeof(char), MAXBUFLEN, fp);
if (ferror(fp) != 0) {
printf("%s %s", error, fileName);
return badReturnValue;
}
int symbol;
while ((symbol = getc(fp)) != EOF) {
putchar(symbol);
}
printf("finish");
fclose(fp);
}
else {
printf("%s %s", error, fileName);
return badReturnValue;
}
}
I think you need a bit more explanations:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// there might be a macro BUFLEN defined in stdio
// which size is optimized for reading in chunks.
// Test if avaiable otherwise define it
#ifndef BUFLEN
# define BUFLEN 4096
#endif
int main(int argc, char *argv[])
{
char source[BUFLEN];
char *filename;
FILE *fp;
size_t fpread, written;
char c;
int ret_fclose;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
// reset errno, just in case
errno = 0;
// work on copy
filename = malloc(strlen(argv[1]) + 1);
if (filename == NULL) {
fprintf(stderr, "Allocating %zu bytes failed\n", strlen(argv[1]) + 1);
exit(EXIT_FAILURE);
}
filename = strcpy(filename, argv[1]);
// try to open the file at 'filename'
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Opening file \"%s\" filename failed\n", filename);
// errno might got set to something usable, check and print
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// You have two options here. One is to read in chunks of MAXBUFLEN
while ((fpread = fread(&source, 1, BUFLEN, fp)) > 0) {
// Do something with the stuff we read into "source"
// we do nothing with it here, we just write to stdout
written = fwrite(&source, 1, fpread, stdout);
// you can use 'written' for error check when writing to an actual file
// but it is unlikely (but not impossible!) with stdout
// test if we wrote what we read
if ((fpread - written) != 0) {
fprintf(stderr, "We did not write what we read. Diff: %d\n",
(int) (fpread - written));
}
}
// fread() does not distinguish between EOF and error, we have to check by hand
if (feof(fp)) {
// we have read all, exit
puts("\n\n\tfinish\n");
// No, wait, we want to do it again in a different way, so: no exit
// exit(EXIT_SUCCESS);
} else {
// some error may have occured, check
if (ferror(fp)) {
fprintf(stderr, "Something bad happend while reading \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
}
// the other way is to read it byte by byte
// reset the filepointers/errors et al.
rewind(fp);
// rewind() should have reseted errno, but better be safe than sorry
errno = 0;
printf("\n\n\tread and print \"%s\" again\n\n\n\n", filename);
// read one byte and print it until end of file
while ((c = fgetc(fp)) != EOF) {
// just print. Gathering them into "source" is left as an exercise
fputc(c, stdout);
}
// clean up
errno = 0;
ret_fclose = fclose(fp);
// even fclose() might fail
if (ret_fclose == EOF) {
fprintf(stderr, "Something bad happend while closing \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// The macros EXIT_FAILURE and EXIT_SUCCESS are set to the correct values for
// the OS to tell it if we had an eror or not.
// Using exit() is noot necessary here but there exits teh function atexit()
// that runs a given function (e.g: clean up, safe content etc.) when called
exit(EXIT_SUCCESS);
}
You read from the file twice but only print once.
If the file is to small the first reading will read all of the contents, and the second reading will not produce anything so you don't print anything.
I believe you have to reset the pointer after using fread.
Try fseek(fp, SEEK_SET, 0) to reset the pointer to the beginning of the file. Then print the file.
Here is my code I am trying to print out info like a Scanner in Java. How can I do so in C?
int main(){
char buffer[1000];
FILE *pFile;
pFile = fopen("randomnumbers.txt", "r");
if(!pFile){
printf("Error : Couldn't Read the File\n");
return 1;
}
}
{
puts(buffer);
}
printf("Success Reading from File\n");
if(fclose(pFile) != 0)
printf("Error : File Not Closed\n");
return 0;
}
I really hope this helps, this is how i could have done it.
int main(){
char buffer[1000];
//I think this means that you only expect there to be a maximum of 1,000
// characters per lines read.
FILE *pFile;
pFile = fopen("randomnumbers.txt", "r");
if(!pFile){
printf("Error : Couldn't Read the File\n");
return 1;
}
}
// You can also read from a file using fscanf
// You pass the file, data type to read and the buffer
// to store it in. You can check for valid data because
// fscanf() returns a number other then 1 if it isn't
// a string
while(fscanf(pFile, "%s", buffer) == 1){
// Puts outputs the string plus a newline.
// Returns a nonnegative integer if it was successful
// and EOF if there was an error
puts(buffer);
}
printf("Success Reading from File\n");
// Closes the text file
if(fclose(pFile) != 0)
printf("Error : File Not Closed\n");
return 0;
}
Replace with this:
int main(){
char buffer[1001]; // i have added one byte because all strings are ending with zero byte
FILE *pFile;
pFile = fopen("randomnumbers.txt", "r");
if(!pFile){
printf("Error : Couldn't Read the File\n");
return 1;
}
int bytesReaded = fread(
buffer, // output buffer
1, // char size is 1
1000, // length of buffer - 1
pFile // opened file
);
// Now you have readed the content of file
// And check if file was readed successfully
if(bytesReaded > 0){
buffer[bytesReaded] = '\0'; // all strings in C are ended with zero byte
// And now you can puts the content to console output
puts(buffer);
} else {
// File not readed successfully or is empty
}
printf("Success Reading from File\n");
if(fclose(pFile) != 0)
printf("Error : File Not Closed\n");
return 0;
}
im trying to read a file and write the content in other file, but the finish file is empty after program execution.
this is the code:
char buf[80];
int main(int argc, char *argv[])
{
int fd;
int fs;
if( (fd=open("salida.txt",O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR))<0) {
printf("\nError %d en open",errno);
perror("\nError en open");
exit(EXIT_FAILURE);
}
if( (fs=open(argv[1],O_CREAT|O_TRUNC|O_RDONLY,S_IRUSR|S_IWUSR))<0) {
printf("\nError %d en open",errno);
perror("\nError en open");
exit(EXIT_FAILURE);
}
int cont = 1;
if(fs=read(fd,&buf,80) < 0){
cont++;
if(write(fd,&buf,80) != 80) {
perror("\nError en el write");
exit(EXIT_FAILURE);
}
}
The condition
if (fs=read(fd,&buf,80) < 0)
doesn't mean
if ((fs = read(fd,&buf,80)) < 0)
it means
if (fs = (read(fd,&buf,80) < 0))
and has the effect of overwriting the file descriptor fs with 0 if the read succeeds, and with 1 if it fails. (read returns the number of bytes read, or -1 on failure.)
You don't want to assign the result to fs in any case, as it means that you're destroying any possibility of writing to the file you opened.
Also, fd is apparently your output file, so it's slightly strange to read from it.
If you want to copy (up to) 80 bytes, you could say something like
int size = 0;
if((size = read(fs, buf, 80)) > 0){
if (write(fd, buf, size) != size) {
perror("\nError en el write");
exit(EXIT_FAILURE);
}
}
Also, truncating the input file (O_TRUNC) may not be the best idea.
You seem to be reading and writing from and to fd. Your code is not very clear, you may want to clean it up. As other answers have pointed out, there are multiple errors in your code and your intentions are not entirely clear.
You should comment your code and indent properly.
int main()
{
char ch;
FILE *source, *target;
source = fopen(source_file, "r");
if( source == NULL )
{
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
target = fopen(target_file, "w");
if( target == NULL )
{
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
return 0;
}
You never closed the files. Most operating systems don't actually make changes to the files until you close them. Until then your changes are only visible in RAM and not on the hard drive. Just add:
close(fd);
close(fs);
To the end of your code.
There seem to be some other problems too (why are you reading from a write-only file and seemingly attempting to write the same data back to it), and it's very much unclear what you're trying to accomplish.
// the following compiles, but the #include statements do expect linux
// so if your using a different OS, you may have to update them.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#define BUFFER_SIZE (80)
static char buf[ BUFFER_SIZE ]; // static so only visible in this file
// note: file scope variables are set to 0 by the startup code
int main( int argc, char *argv[])
{
int fd = -1; // destination file descriptor
int fs = -1; // source file descriptor
int statusRd = 0; // returned value from read
int statusWr = 0; // returned value from write
if( 2 > argc )
{ // then, file name parameter missing
printf( "\ncalling format: %s <filenametoread>\n", argv[0]);
exit( EXIT_FAILURE );
}
// implied else, proper number of parameters
// note: there should be a call to 'stat()'
// to assure input file exists placed here
// open destination file, uses fixed name
if( (fd = open("salida.txt", O_TRUNC | O_CREAT | O_WRONLY, S_IWRITE) ) <0)
{
printf("\nError %d en open",errno);
perror("open for write failed");
exit(EXIT_FAILURE);
}
// implied else, open of destination file successful
if( (fs=open(argv[1],O_RDONLY,S_IREAD))<0)
{
printf("\nError %d en open",errno);
perror("open for read failed");
close(fd); // cleanup
exit(EXIT_FAILURE);
}
// implied else, open of source file successful
do
{
if( (statusRd = read(fs,&buf, BUFFER_SIZE)) < 0)
{ // then read failed
perror( "read failed" );
close(fs); // cleanup
close(fd); // cleanup
exit( EXIT_FAILURE );
}
// implied else, read successful
if( 0 < statusRd )
{ // then some bytes read
if( ( statusWr = write(fd, buf, statusRd)) < 0)
{ // then, write failed
perror("\nwrite failed");
close(fs); // cleanup
close(fd); // cleanup
exit(EXIT_FAILURE);
}
}
} while( statusRd > 0 ); // exit loop when reach end of file
close(fs);
close(fd);
return(0);
}