I wanted to know whether there is a piece of code that can help me with making a new file with a different name every time the function with that code runs, for instance I want to write this
FILE * new_file = fopen("D:\C\data\1.txt", "w +" );
as
FILE * new_file = fopen("D:\C\data\%d.txt", next_number, "w +" );
that next_number comes from another procedure which always will get the number following a number stored in a different file.
You can use snprintf().
Example:
char file_name[100]; // assuming path length is at most 100
snprintf(file_name, sizeof(file_name), "D:\\C\\data\\%d.txt", next_number);
FILE * new_file = fopen(file_name, "w+" );
Related
What is the best way to append line(s) to a file?
Currently I am using the following script:
/**
* Append the `line` to the file given at the `path`.
*
* #param path
* The absolute or relative path to the file with
* extension
* #param line
* The line to append
* #param [max_lines=10000]
* The maximum number of lines to allow for a file
* to prevent an infinite loop
*/
void append(string path, string line, number max_lines){
number f = OpenFileForReadingAndWriting(path);
// go through file until the end is reached to set the
// internal pointer to this position
number line_counter = 0;
string file_content = "";
string file_line;
while(ReadFileLine(f, file_line) && line_counter < max_lines){
line_counter++;
// file_content += file_line;
}
// result("file content: \n" + file_content + "{EOF}");
// append the line
WriteFile(f, line + "\n");
CloseFile(f);
}
void append(string path, string line){
append(path, line, 10000);
}
string path = "path/to/file.txt";
append(path, "Appended line");
For me it seems a little bit odd to read the whole file content to just append one line. If the file is very big, this probably is very slow1. So I guess there is a better solution of this. Does anyone know this solution?
Some background
My application is written in python but executed in Digital Micrograph. My python application is logging its steps. Sometimes I am executing dm-script from python. There I have no possibility to see what is going on. Since there is a bug, I need something to find out what is going on. Therefore I want to add logging to dm-script too.
This also explains, why I want to open and close the file every single time. This takes more time, but I don't care about execution speed while debugging. The logs will either be removed or switched off for the normal version, as usual. But on the other hand I am executing dm-script and python alternating so I have to prevent python blocking the file for dm-script and the other way around.
1As written in the background, I am not really interested in speed. So the current script is enough for me. Still I am interested in how to do this better, just for learnings and curiositys sake.
The best way to deal with any files in DM-script (binary or text) is to use the streaming object. The following example should answer your question:
void writeText()
{
string path
if ( !SaveAsDialog( "Save text as" , path , path ) ) return
number fileID = CreateFileForWriting( path )
object fStream = NewStreamFromFileReference( fileID , 1 ) // 1 for auto-close file when out of scope
// Write some text
number encoding = 0 // 0 = system default
fStream.StreamWriteAsText( encoding , "The quick brown dog jumps over the lazy fox" )
// Replace last 'fox' by 'dog'
fStream.StreamSetPos( 1 , -3 ) // 3 bytes before current position
fStream.StreamWriteAsText( encoding, "dog" )
// Replace first 'dog' by 'fox'
fStream.StreamSetPos( 0 , 16 ) // 16 bytes after start
fStream.StreamWriteAsText( encoding, "fox" )
// Append at end
fStream.StreamSetPos( 2 , 0 ) // end position (0 bytes from end)
fStream.StreamWriteAsText( encoding, "." )
}
writeText()
When trying to open a file with fopen(path, "2"); i get NULL on an existing path
iv'e tried to enter only the file name and it works but i want the program to write the file in the path...
Yes, i write the path with double backslashes "\\" when it's necesary.
Yes the path without doubt exists.
FILE* log;
char directory_path[PATH_LEN] = { 0 };
char directory_file[PATH_LEN] = { 0 };
//directory_path is the directory, entered by the user
//LOG_NAME is the files name without the path - "log.txt"
//#define PATH_LEN 100
printf("Folder to scan: ");
fgets(directory_path, PATH_LEN, stdin);
directory_path[strlen(directory_path) - 1] = 0;
//this section connects the path with the file name.
strcpy(directory_file, directory_path);
strcat(directory_file, "\\");
strcat(directory_file, LOG_NAME);
if ((log = fopen(directory_file, "w")) == NULL)
{
printf("Error");
}
My program worked until i tried to write into a file in order to create a log file. This means that the path is correct without doubt.
Can anyone tell me the problem here?
You have several issues in your code:
For one, fopen(path, "2"); is not valid.
The mode argument needs to include one of a, r, and w and can optionally include b or +.
As another thing, directory_path[strlen(directory_path) - 1] = 0; may truncate the end of your path (if it's over PATH_LEN characters long).
There also may be a possible issue with buffer overflow due to the fact that you copy a string to a buffer of the same size and then concatenate two other strings to it. Therefore, you should change this line:
char directory_file[PATH_LEN] = { 0 };
to this:
char directory_file[PATH_LEN+sizeof(LOG_NAME)+1] = { 0 };
To debug this issue, you should print the string entered and ask for confirmation before using it (wrap this in #ifdef DEBUG).
So I am trying to write a begginers program in which it is necessary to create a series of files, depending on the users choosing option, and where the first file created should be name by for example "book1.txt" and second one "book2.txt" etc...
FILE *fnew;
int num; //i do have a lot of code before to get the 'num' value from where I want, don't bother it;
char filename[]= "bookX.txt";
filename[4]=num+1;
fnew = fopen(filename,"w");
fclose(fnew);
You can use sprintf to build the filename:
sprintf(filename, "book%03d.txt", num);
This will create files named booknnn.txt, where nnn is the number in question padded with 0's, ex. book001.txt, book002.txt.
I want to make a program (network server-client).
One of the specification for this program is next:
The server will receive the sent packages and save it into a file, with a unique name (generated by the server at the moment the transfer starts.
Ex __tf_"unique_random_string".txt
I made a function that returns a pointer to a "unique" string created.
The problem is: If i stop the server and then start it again it will generate the same names.
Ex:this file names were generated and then i stopped the server.
__ft_apqfwk.txt
__ft_arzowk.txt
__ft_cdyggx.txt
I start it again and i try to generate 3 file names. Them will be the same.
Sorry for my english. I'm still learning it.
My function to generate this "unique string" is:
char *create_random_name(void)
{
const char charset[] = "abcdefghijklmnopqrstuvwxyz";
char *file_name;
int i=0;
int key;
if((file_name = malloc(16 * sizeof ( char )) ) == NULL)
{
printf("Failed to alloc memory space\n");
return NULL;
}
strcpy(file_name,"__ft_");
for(i=5 ; i<11 ; i++)
{
key = rand() % (int)(sizeof(charset)-1);
file_name[i]=charset[key];
}
strcat(file_name,".txt");
file_name[15] = '\0';
return file_name;
}
One option is saving to a file the names that have been used, and using them as a checklist. You also want to seed rand with something like srand(time(NULL)).
another is ignoring the randomisation, and just going in order, e.g. aaa, aab aac...aba ,abb etc. Again, save where your cycle is up to on a file.
Your question seems a little bit unclear but if you want to generate a unique string there are a couple of things you can consider:
Get System timestamp ( yyyy-MM-dd-HH-mm-ss-fff-tt)
Use Random function to generate a random number
Combine this with your function and I am sure you will get a unique string.
Hope it helps !
If it's available, you could avoid manually generating random names that might collide and let the system do it for you (and handle collision resolution by creating a new name) by using mkstemps. This is also safer because it opens the file for you, removing the risk of a random name being generated, verified to be unique, then trying to open it and discovering another thread/process raced in and created it.
char name[] = "/path/to/put/files/in/__ft_XXXXXX.txt";
int fd = mkstemps(name, strlen(".txt"));
if (fd == -1) { ... handle error ... }
After mkstemps succeeds, name will hold the path to the file (it's mutated in place, replacing the XXXXXX string), and fd will be an open file descriptor to that newly created file; if you need a FILE*, use fdopen to convert to a stdio type.
Before calling rand(),--- once and only once---, call srand(time()) to initialize the random number generator.
Before settling on any specific file name, call stat() to assure that file name does not already exist.
I want to open a file abc.txt present in "../ab cd/Output" folder.
What I have done so far is:
char temp1[100], temp2[10] = "abc.txt";
strcpy(temp1, "../ab\ cd/Output/");
FILE *fp_minenergy = fopen(strcat(temp1, temp2), "r");
On executing it gives segmentation fault.
The problem should be just the file path itself
fopen("../ab cd/Output/abc.txt", "r");
Your actual path is not valid "../ab\ cd/Output/abc.txt", you don't need to escape here anything.
char dirname[51] = "/the/directory";
char filename[51] = "the_file_name.txt";
char full_name[101] = strcat("/the/directory","/");
char full_name = strcat(full_name,filename);
FILE *fp_minenergy = fopen(full_name, "r");
I am adding an extra strcat for the / because I don't know where the directory name is coming from. Someone may specify it without the trailing /. If they specify the / in the name, it doesn't hurt.
/dir/one is equal to dir//two