Why am I unable to create this file? - c

Here is my code example:
int main(int argc, char* argv[])
{
char* fileName = "%appdata%\\log.log";
FILE *file;
file = fopen(fileName, "a+");
time_t startTime = time(0);
fputs("Started logging at: ", file);
fputs(ctime(&startTime), file);
fclose(file);
printf("%s", fileName);
return 0;
}
My program gets down to the printf() statement, and prints:
%appdata%\log.log
I know that is a viable location for a Windows computer, so why is the program unable to make the .log file? What is a workaround that I should use to make it work?

the fopen call has no idea what %appdata% is, as it can't magically convert that into a path. You have to expand the path yourself using the ExpandEnvironmentStrings function. e.g. (untested):
char dest[MAX_PATH];
ExpandEnvironmentStrings(fileName, dest, MAX_PATH);
file = fopen(dest, "a+");

%appdata%
is an environment variable, they are not automatically resolved and need their values to explicitly be retrieved using getenv function call.

Related

callback on write to file success, C

Trying my hand at writing some C scripts, I have some code that should save a string to a file before rebooting the system. Both work separately but trying to write to file immediately before rebooting fails...
int writeToConfFile(char* filename, char* newConf) {
FILE *fp;
int status;
fp = fopen(filename, "w");
fprintf(fp,"%s",&newConf[0]);
status = fclose(fp);
return status;
}
int main(int argc, char **argv){
char extraString[1024];
strcpy(extraString,"0");
writeToConfFile("/etc/filename", extraString);
reboot(RB_AUTOBOOT);
}
adding sleep(10) between writeToConfFile and reboot does the trick, but I would like to do it in a neater way.
edit: the os is a heavily customized legacy debian.
edit2: tried changing writeToConfFile to end like this:
fp = fopen(filename, "w");
fprintf(fp,"%s",&newConf[0]);
fflush(fp);
status = fclose(fp);
return status;
but it didn't work either
As mathieu and jamieguinan suggested, calling sync() before reboot makes sure changes are written to disk
so the code ends thus:
writeToConfFile("/etc/filename", extraString);
sync();
reboot(RB_AUTOBOOT);

How can I refer to a file as the stream for fgets()?

fgets() returns a string from a provided stream. One is stdin, which is the user input from the terminal. I know how to do this, but if I am using compiled c code in applications, this is not very useful. It would be more useful if I could get a string from a file. That would be cool. Apparently, there is some way to provide a text file as the stream. Suppose I have the following code:
#include <stdio.h>
int main(int argc, const char *argv){
char *TextFromFile[16];
fgets(TextFromFile, 16, /*stream that refers to txt file*/);
printf("%s\n", TextFromFile);
return 0;
}
Suppose there is a text file in the same directory as the c file. How can I make the printf() function print the contents of the text file?
Given the following is defined;
char *TextFromFile[16];
char TextFromFile[16]; //note "*" has been removed
const char fileSpecToSource[] = {"some path location\\someFileName.txt"};//Windows
const char fileSpecToSource[] = {"some path location/someFileName.txt"};//Linux
From within a function, the statement:
FILE *fp = fopen(fileSpecToSource, "r");//file location is local to source directory.
if successful (i.e. fp != NULL), fp can be used as the stream argument in:
fgets(TextFromFile, 16, fp);
Later I found out the problem. fopen is stupid. Using ./file.txt or others will not work. I need to use the whole file path to do it.
FILE (*File) = fopen("/home/asadefa/Desktop/txt.txt", "r");
char FData[0x100];
memset(FData, '\0', 0x100);
for(z = 0; z < 0x100; ++z) {
fgets(FData, 0x100, File);
}
fclose(File);
I should have noted that the full file path is used.

How to retrieve the file that is outside of current directory using format specifier?

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.

Variable Substitution in C

I want to open a file. Easy enough. Use fopen(). However, what file to open depends on the user input. I am somewhat proficient in Korn Shell scripting and this is easily done using variable substitution: $(var). I am unable to figure out the correct format in C. Could someone please give me some insight?
My code -
#include <stdlib.h>
#include <stdio.h>
char statsA[100];
char fileA[50];
int main (void)
{
printf("Enter file to open\n");
gets(fileA);
FILE *statsA;
statsA = fopen("c:/Users/SeanA/C/***<fileA>***", "r+");
.......................................^ What goes here?
I am unsure of how to include the user input in the fopen string.
This is what sprintf is for. It works like printf, except that its output goes to a string instead of stdout.
char filename[100];
sprintf(filename, "c:/Users/SeanA/C/%s", fileA);
statsA = fopen(filename, "r+");
Also, the definition of statsA you have inside of main masks the definition at file scope. You probably want to give these different names.
You must concatenate both strings manually. Something like this
char* folder = "c:/Users/SeanA/C/";
char* path = malloc(strlen(fileA) + strlen(folder) + 1);
path = strcpy(folder);
path = strcat(fileA);
FILE *statsA = fopen(path, "r+");
free(path);//Always free your memory
Do scanf to get the file from the user.
make a char array to hold the filename.
char filename[15];
Now ask for the file name:
printf("What is the name of the file?\n");
scanf("%s", &filename);
Note: Include the FULL file name. so if I have a text doc called filename The user would need to type filename.txt
Now you have the file name you can declare a file pointer
FILE * fp;
fp = fopen(filename, "r");
Now you should be able to scan your file!
fscanf(fp, "%d", &value);
EDIT: I did not notice you wanted string concatenation with your file path.
Since you know the predefined path you can make another char array that holds that string path
char fullPath[100];
char path[75] = "c:/Users/SeanA/C/";
Now you can use strcat to bring them all together!
strcat(fullPath, path);
strcat(fullPath, filename);
Now you do fopen(fullPath, "r");

How to write file inside folder in current directory using fopen

I want to write to a file, that is inside a folder in the current working directory, with the file name being the number value that is passed to the function.
void record_data(number[]) {
FILE *fptr;
fptr = fopen("./folder/number", "w");
}
I'm unable to do so in this way (it names the file as number).
How can I do this properly?
Assuming you meant int number as opposed to your number[] which is not valid C.
You can use sprintf(), or preferably snprintf():
void record_data(int number) {
char str[255]; //Large enough buffer.
snprintf(str, sizeof(str), "./folder/%d", number);
FILE *fptr;
fptr = fopen(str, "w");
}
And consider calling fclose() on your FILE * when you're done using it.

Resources