I'm a complete noob to C and I wondered why if I take a user input why it wont find the file but when I hard code it using:
const char * fn = "/Users/james/Documents/test.rtf";
It seems to work fine?
char text[100];
fputs("File location: ", stdout);
fflush(stdout);
fgets(text, sizeof text, stdin);
FILE *fp = fopen(text,"r");
if( fp ) {
printf("\nFile Exists");
fclose(fp);
} else {
printf("\nFiles doesn't exist");
}
Any help would be awesome, or just a point to some online source that I have clearly not been able to find.
:)
fgets reads a line and keeps the final newline character. You'll have to strip that off by
text[strlen(text) - 1] = '\0';
(After doing the proper error checking, of course.)
You can use access() to check whether file exists or not
For access you need to provide path of the file and mode.
Prototype of access is
int access(const char *pathname, int mode);
access() returns zero if file exists.
For more information visit: http://linux.die.net/man/2/access
Related
char * read_file(char * filename) {
char * file_contents = malloc(4096 * sizeof(char));
FILE * file;
file = fopen(filename, "r");
fread(file_contents, 4096, sizeof(char), file);
fclose(file);
return file_contents;
}
char * read_flag() {
return read_file("/flag.txt"); // outside of current working directory ;)
}
int main(int argc, char* argv[]) {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
char * flag = read_flag();
char input_filename[40];
//Current directory is /home/problem
printf("Current working directory is: ");
system("pwd");
printf("Enter a filename to print the contents of the file => ");
scanf("%39s", input_filename);
while ((directory_entry = readdir(directory)) != NULL) {
if (strcmp(input_filename, directory_entry->d_name) == 0) {
printf("File contents:\n");
printf("%s\n", read_file(input_filename));
return 0;
}
}
}
I need to open a file that is outside of this directory ("/flag.txt"). I have tried something like "../" in the input to get out from this directory but it is not working. I am not sure how do i enter the filename such that it can retrieve the file that is outside of the /home/problem directory. I am currently using Ubuntu to do this. I think the idea should be using something like %s%d when i enter my input. Is this possible to use any specifier or exploit this program in order to read the entire contents?
You need to pass the full path to your file if it is outside the solution directory either with \\ or one /. On a windows based system this would be for example C:\\folder\\file.txt. I do not use linux currently, but it should be /home/folder/file.txt.
The fopen function can fail, and you should handle that. Read fopen(3), open(2), path_resolution(7), errno(3) to understand the possible failure reasons. Details could be file system and computer specific (and could include hardware failures).
I recommend using perror(3) and exit(3) on failure (don't forget to include both <stdio.h> for perror and <stdlib.h> for exit):
FILE* file = fopen(filename, "r");
if (!file) {
perror(filename);
exit(EXIT_FAILURE);
}
then you'll get a meaningful error message (into stderr) on failure
My guess: your root file system (and root directory / ...) don't have a flag.txt file and you might want to retrieve what your shell understands from ~/flag.txt. Perhaps you want to retrieve it in your home directory (then build its file path, using getenv("HOME") on Linux or Unix; see this).
Read also about globbing, and glob(7).
Read also some Linux programming book, perhaps the old ALP.
Right now, what I have is this:
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main()
{
char fname[100];
FILE* fp;
memset(fname, 0, 100);
/* ask user for the name of the file */
printf("enter file name: ");
gets(fname);
fp = fopen(fname, "w");
/* Checks if the file us unable to be opened, then it shows the
error message */
if (fp == NULL)
printf("\nError, Unable to open the file for reading\n");
else
printf("hello");
getch();
}
This functions just fine, but is there a way I can force it to save as a .txt or a .data or something? Right now it just saves as the name you put in with no extension. Other than asking the user to just input the name and extension, I can't think of a way to do that. I mean, it still works just fine for reading/writing purposes, I just think an extension would be nice.
to expand my comment:
strcat(fname, ".txt");
The strcat function can be used to append text to a destination buffer, assuming the destination is large enough to store the new text.
char *strcat(char *destination, const char *source);
The source is the new text that you want to append (in your case the extension), and the destination is where the new text will be added. If destination is not big enough, then the behavior is undefined.
One could also use the snprintf function to append text, which is safer, as it takes a size argument.
I figured it out. Credit goes to a friend of mine who showed this to me earlier today.
int main()
{
FILE *Fileptr;
char filename[50];
char file[50];
int c;
printf("What do you want to name your file?");
scanf("%s", filename);
sprintf(file, "%s.txt", filename);
Fileptr = fopen(file, "w");
fprintf(Fileptr, "Data goes here");
fclose(Fileptr);
return 0;
}
Much easier than what I had been doing.
I'm trying to have the program check, that, if a user inputs nothing the print statement will say it cant find the file name, but the issue I'm having is that the command line will just go to a new line after hitting enter instead of saying the print statement.
This is the code here. I was told that Null is the place holder for if nothing is put in so I thought it would work.
int main()
{
FILE *fin;
FILE *fout;
char fInName[50];
char fOutName[50];
printf("pleas type input file, and output file please type legibly\n ");
scanf("%s %s", &fInName, &fOutName);
fin = fopen(fInName, "r");
fout = fopen(fOutName, "r");
if (fInName == NULL && fOutName == NULL)
{
printf("Error: Cannot open input file %s.", fInName);
}
else if (fInName != NULL && fOutName == NULL)
{
printf("file found");
}
}
What im trying to test is if a first file name is entered and the second isnt then print the statement. If both arent entered then print file does not exist.
there is more to the code to see if the file exists or not, but thst would be a bit much, now Im just trying to understand why it wont read unentered data.
Ive tried looking at examples such as: How to detect empty string from fgets
and tried to alter the code to fit that type of style but it didnt work for me so Im giving you the code it was originally so that anything helpful wouldnt confuse me more.
Edit:
okay so I tried to do a simple code in order to see what may be the cause of this issue:
int main()
{
char firstname[50];
char lastname[50];
char nothing [0];
printf("pleas type input file, and output file please type legibly pwease\n ");
scanf("%s" "%s", firstname, lastname);
if (firstname == lastname )
{
printf("Error: Cannot open input file %s.", firstname);
}
else
{
printf("file found");
}
}
I ran the code using adam and either if I typed adam (space) adam or adam(enter) adam the program thinks that the input is not the same, I feel like that would help identify why it doesnt know why nothing is typed in.
The problem is occurring when you try to check if fInName == NULL.
The problem is that fInName is just a variable that you're using to store the name of the file that you want to open. What you actually want to check is that the user gave you a valid filename, and to do so you will want to understand what the return value of functions are.
For example, when you try to open a file using fopen(), if fopen() is unable to successfully open the file, say because the user didn't input anything or misspelled the filename, then fopen() will return NULL, storing it in whatever variable you assigned it to (in your case, *fin and *fout).
Also, scanf() is not recommended for char arrays because if the user inputs more data than you allocated for the array, which in this case is enough space for 50 characters, then scanf() will try to write data to memory that's not yours, causing a buffer overflow.
A much safer option is to use fgets() because you can choose exactly how much data is written into your char array, with the only downside being that fgets() will write newline characters \n (caused by hitting the enter key) into the array, though the simple solution is to overwrite the newline character with '\0'.
Therefore, I would propose:
int main(void)
{
char fInName[50];
char fOutName[50];
// ensure proper usage
do
{
printf("What file would you like to open? ");
// get infile from user and remove trailing newline '\n' character
fgets(fInName, 50, stdin);
fInName[strcspn(fInName, "\n")] = '\0';
}
// prompt for input until user enters something
while (strlen(fInName) < 1);
do
{
printf("What file would you like to output to? ");
// get outfile from user and remove trailing newline '\n' character
fgets(fOutName, 50, stdin);
fOutName[strcspn(fOutName, "\n")] = '\0';
}
// prompt for input until user enters something
while (strlen(fOutName) < 1);
FILE *fin = fopen(fInName, "r");
if (fin == NULL)
{
printf("Error: Cannot open input file %s.", fInName);
return 1;
}
else
{
printf("file found");
}
}
What I want to do is to read the contents of a '.d' binary file and store them in an array.
So I wrote the following codes:
void viewFile()
{
unsigned char inFileData[SIZE];
char fileName[SIZE];
int numRead;
FILE *inBinFile;
printf("Enter the file name:");
scanf("%s", fileName);
inBinFile = fopen( fileName, "rb");
if(( inBinFile = fopen(fileName, "rb")) == NULL )
{
fprintf( stderr, "Error opening %s\n", fileName );
clearStdin();/*a function to clear stdin*/
mainMenu();/*a function to prompt user input*/
}
numRead = fread( inFileData, sizeof(unsigned char), SIZE, inBinFile );
inFileData[SIZE] = '\0';
printf("U coded data:\n%s\n", inFileData);
printf("%d\n", numRead);
fclose(inBinFile);
return;
}
the output is an unreadable pile of junk. Which part did I do wrong? I don't get it.
also, I wrote my clearStdin function as below:
void clearStdin(void)
{
scanf("%*[^\n]");
scanf("%*1[\n]");
return;
}
compiler reported no errors, but somehow the function call doesn't seem to work exactly the way I wanted. It did clear stdin, but there are always errors closely following wherever this function is called, eg., the mainmenu function to prompt user input.
Please help!! thanks in advance.
"the output is an unreadable pile of junk" - yes, it will be. It's a binary file, it's not meant to be readable as text.
If you want to see binary information in a readable form, think about doing a hex dump of it.
See here for a way to do this.
My goal is to gather input and open files based on that input.
FILE*
open_input_file (char* fileName) //opens source file to be read
{
return fopen(fileName, "r");
}
In an earlier function, I collect input from the user and save it to fileName. When I debug the program, it tells me fopen is returning NULL. That's not what I want, and I'm not sure where the problem is.
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
inFile = open_input_file(infileName);
}
I don't know what the problem is. Any thoughts?
If fopen returns NULL, the open failed. errno will hold the failure code and strerror(errno) will return a short description of why the open failed.
#include <errno.h>
#include <string.h>
...
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
if (!(inFile = open_input_file(infileName))) {
fprintf(stderr, "Error opening '%s': %s\n",
infileName, strerror(errno));
} else {
// open successful
...
}
}
Off-topic
gather_input better make sure infileName is null-terminated to prevent buffer overflows. The simplest way to do this is to define the size of the file name buffer as a macro and set the last character to 0.
#define FILENAMELEN 32
void gather_input(char infileName[]) {
...
infileName[FILENAMELEN-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[FILENAMELEN] = {'\0'};
This isn't very flexible. You could instead pass the size of the file name buffer into gather_input.
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
void gather_input(char infileName[], size_t len) {
...
infileName[len-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName, LENGTH(infileName)); // infileName is an output parameter for this
An alternative to setting the last character, if using standard string manipulation functions, is to use the strl* functions (strlcpy and strlcat) rather than their unbounded cousins. If you aren't using strl*, you should be using strncpy and strncat.
Have you checked that the file pointed to by inFilename exists on your HDD ?
Check the value of infileName in your debugger or put a printf statement to show the value on screen. printf("'%s'\n", infileName);
Did you call fclose() on your file inside the open_input_file() call. Maybe the file is still locked ?
Edit: I just checked the code. I have modified your english_to_morse() function. 1. The while statement is easier to follow than the for. 2. fgetc() returns an int and not a char.
At the top of the initialise I added this. This initialises every string in the array with and undefined string of ".??.". This will make it easier to find strange bugs as everything in your array is at least initialised.
I have modified different sections of the code but you should be able to follow.
initialize_morse_alphanum (char morseStrings[91][6])
{
for (int i=0;i<91;i++)
strcpy(morseStrings[i], ".??.");
....
....
void
english_to_morse(FILE* inputFile, FILE* outputFile, char morseStrings[91][6])
{ int convert;
convert = fgetc(inputFile);
while (convert != EOF)
{
fputs(morseStrings[convert], outputFile);
fputc(' ', outputFile);
printf ("%s ", morseStrings[convert]);
convert = fgetc(inputFile);
}
}
open_output_file (char* fileName) //opens destination file to be written
{ FILE* handle = NULL;
handle = fopen (fileName, "w"); <---- Remove the * from filename
return handle; }
Also, as mentioned in a different answer, it would be good to add some bounds checks to different areas of the code. At the moment it is quite prone to crashing. If my input file contains a lowercase 'a' (ascii 96) your program will be accessing memory that is out of bounds. So you should add a line like if (convert >= '0' && convert <= 'Z') in there somewhere. I will let you work that out.
Make sure that gather_input works properly. Could it be a problem because you're trying to read a file you're also writing on? In this case, try to close and open again the stream.