Linking separate C programs together - c

I'm need some help on a project, the plan is to make a C program that can take an input file name and then do these three tasks:
copy it's contents and store it's duplicate in another user specified location
change the backup file's format, i.e from ".txt" to something like ".img"
encrypt the contents of the file (any cypher method)
Note: the input file name has to be scanned during execution
I and my team have already made about 75% of it but it's in separate parts like each of the following three tasks is an individual program,
and we are having trouble combining them.
Another error is that we are using "rename" function from files concept to copy files and change their format and we don't have any idea of how to use scanf to read the file name and give it as input to the rename function.
So if you could give me any suggestions..I'd really be grateful.

It's been a little while since I've used it, but you could consider using make and creating a makefile. According to what I have seen from the references I've looked up, a basic makefile looks kind of like this.
makefile.h:
basicMakefile: basicMake1.c, basicMake2.c, basicMake3.c
gcc -o basicMakefile basicMake1.c basicMake2.c basicMake3.c -I
As for using scanf, suppose we have
char str1[20]; //creates a char array(a string) that is 20 chars long
printf("Enter the new name for the file: ");
scanf("%s" , str1); //puts the user entered value into str1
you could then do
rename(str1) //function call with the new filename
//whatever your rename funtion does for the logic
Below are the references that I used, I would strongly recommend taking a more in-depth look at these as they explain these concepts in more detail than what I could fit in here. My above examples are derived from the ones found in them.
Make Documentation: https://www.gnu.org/software/make/manual/make.html
Scanf Tutorial: https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
Simple Makefile Tutorial: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

Related

C File Save and Restore input information

I have a program based on a struct with different information.
In this program you can for example add people and delete people etc. I already have all this done, so the program it self is done. But the files are not.
So I am trying to write a code that "saves" if I would for example add a person and this would "save" when I choose to exit the program. And a code that "restores" the people in the file in the beginning of the program.
Does any one have any ideas or tips? I'm new to programming and trying to learn. I have been sitting with this for a few days.
Before I "restore" I ask for an file to open and if this file does not exist a new one is created and this works. So if I would have a file with 3 employees and I would open this file I would want to restore them and then being able to add more employees to the file etc.
You have to write (and to read) in two steps: first the struct, and then the array the struct points to.
Code fragment for writing (a.o. without error checking, that is however needed):
#include <stdio.h>
// ...
employees emp;
const char* filename="your_filename";
// populate emp;
FILE* file = fopen(filename,"w");
fwrite(&emp,sizeof(employees),1,file);
fwrite(emp.pic,sizeof(int),emp.imageCount,file);
fclose(file);
Now you have the array after the struct in your file. Read it in the same way:
FILE* file = fopen(filename,"r");
fread(&emp,sizeof(employees),1,file);
emp.pic=calloc(sizeof(int), emp.imageCount);
fread(emp.pic,sizeof(int),emp.imageCount,file);
Please don't forget to check for errors (see man fopen|fread|fwrite|calloc). In case you have several structs, you must repeat the two steps for any element.
What is the platform? For Windows there is simple format of .INI files with contents like:
[Employee_1]
id=123
name=Smith
imageCount=2
...
You can use GetPrivateProfileString/GetPrivateProfileInt and WritePrivateProfileString API functions to read and store the information. Use separate section for each employee. One common section is necessary to store the number of employee sections.

Program to compile files in a directory in openedge

Could someone help me in writing a program that has to compile all the files in the directory and report error, if any. For which my program has to get the list of all files under the folder with its full path and store it in a temp-table and then it has to loop through the temp table and compile the files.
Below is a very rough start.
Look for more info around the COMPILE statement and the COMPILER system handle in the online help (F1).
Be aware that compiling requires you to have a developer license installed. Without it the COMPILE statement will fail.
DEFINE VARIABLE cDir AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFile AS CHARACTER NO-UNDO FORMAT "x(30)".
ASSIGN
cDir = "c:\temp\".
INPUT FROM OS-DIR(cDir).
REPEAT:
IMPORT cFile.
IF cFile MATCHES "*..p" THEN DO:
COMPILE VALUE(cDir + cFile) SAVE NO-ERROR.
IF COMPILER:ERROR THEN DO:
DISPLAY
cFile
COMPILER:GET-MESSAGE(1) FORMAT "x(60)"
WITH FRAME frame1 WIDTH 300 20 DOWN.
END.
END.
END.
INPUT CLOSE.
Since the comment wouldn't let me paste this much into it... using INPUT FROM OS-DIR returns all of the files and directories under a directory. You can use this information to keep going down the directory tree to find all sub directories
OS-DIR documentation:
Sometimes, rather than reading the contents of a file, you want to read a list of the files in a directory. You can use the OS–DIR option of the INPUT FROM statement for this purpose.
Each line read from OS–DIR contains three values:
*The simple (base) name of the file.
*The full pathname of the file.
*A string value containing one or more attribute characters. These characters indicate the type of the file and its status.
Every file has one of the following attribute characters:
*F — Regular file or FIFO pipe
*D — Directory
*S — Special device
*X — Unknown file type
In addition, the attribute string for each file might contain one or more of the following attribute characters:
*H — Hidden file
*L — Symbolic link
*P — Pipe file
The tokens are returned in the standard ABL format that can be read by the IMPORT or SET statements.

File pointers in an array

Very raw with C. I'm writing a program that takes files as it's arguments, but this is rather annoying for debugging (GDB). Rather than have to re-type the file list each time that I start off in GDB, I'd rather store the file names in an array and modify the program to read this array rather than the argv[] values.
I started out with
FILE*[5] inpFiles;
inpFiles[0] = &file1.txt;
but this is all wrong. I need to get some sort of reference to each of the input files so that I can get its memory address.
How can I do this? Thanks.
You can define a GDB command in .gdbinit so you don't need to modify your production code.
For example, add the following lines in your ~/.gdbinit or .gdbinit in your working directory.
define do
run file1.txt file2.txt file3.txt file4.txt file5.txt
end
Then, in GDB, just type the command do, and GDB runs run file1.txt file2.txt file3.txt file4.txt file5.txt for you.
You can parse your input files, containing each of your files, by reading on the standard file stream 0.
so that you could do this:
./your_program < your_input_file
and in gdb,
run/r < your_input_file
but if you want to keep your args method, you can also do this:
./your_program `cat your_input_file`
Hope this helps.
An array of FILE * would be written:
FILE *inpFiles[5];
This can store the values returned from fopen() or a similar functions; it does not store file names.
You might store the file pointer into the structure that &file1 represents, or you might create a new structure that stores the name and the opened file pointer (though you may need to specify a mode; presumably "r" or "rb" by default).
So, clarify to yourself what exactly you want to do. You can create an array of file pointers, or an array of structures containing, amongst other things, a file pointer. But you have to decide how you're going to use it and what the semantics are going to be.
This presumes that modifying the program is a better idea than using GDB better. If you can learn to use the facilities of GDB more powerfully, then that's a better idea.
For example, can you make it easy to specify the files by using a metacharacter:
run debug?.txt
where your files are debug0.txt, debug1.txt, ...?
The other answers also suggest alternatives.

C - Deleting / Modifiying A line From A File

I have a datas.txt file :
format : name surname debt payment
bir bir 100 2
iki iki 200 2
eray alakese 100 5
john doe 2000 10
I'm learning C and i know just simple file functions (fscanf, fprinf, fopen etc.)
I'll
ask user name and surname with scanfand then assign them to name and surname variables.
It will search file for name and surname and then assign debt and payment to debt, payment variables ( fscanf(file, "%s %s %d %d", name, surname, &debt, &payment);)
Delete or modify this line
This is my source code .
scanf("%s", &name);
scanf("%s", &surname);
file = fopen("datas.txt", "r");
/* this fscanf() is working as expected. There is no problem. */
fscanf(file, "%s %s %d %d", name, surname, &debt, &payment);
/* modify and delete actions here */
fclose(file);
Examples :
I want to delete record of "John Doe" .
I want to decrease "John Doe"'s debt to 100$
You cannot delete/modify[*] individual lines of a text file; the only solution is to 1) create a new temporary file, 2) copy the contents up to, but not including, the line that you want modified/deleted, 3) output the modified line, 4) copy the rest of the original file, 5) replace the old file with the temporary file.
[*] Modification is possible ONLY if the modified line has the same length as the original line.
EDIT: PS: Using fgets, followed by sscanf (or some other way of tokenizing the line) will save you much grief.
This is a little hard to do, because C's model of files, inherited from Unix (they were largely codeveloped), does not actually define a file as a list of lines. Instead, it defines a line as a string of bytes terminated with a newline, and a file (roughly) as a stored string of bytes of potentially limited length, where you can possibly skip to different parts. That's considerably vague, but bear with me.
Whe problem becomes clearer when we try to translate our ideas - "modify this line", "delete that line" - into file operations. We can read a line by just stopping at a newline, but there's simply no command to cut it into sections; only to set the end (ftruncate()). So to change the size of the line, we need to copy all the data that follows it. It can be done, but it's very often easier to just create the file anew. Compare the subtleties of implementing memmove().
The traditional method to do this comes in two variants, depending on what side effects you can tolerate.
One is to write your updated version in another file, and then rename() it into place. This has the advantage that the new file will be complete by the time you put it in place, but the downsides that it may not match the old file precisely as far as permissions etc go, and it won't be visible to other programs that already had the old one open. If two programs modify the file like this, it's a race condition as one of the changes gets overwritten by the other.
The other is to load the data completely and write the modified version down in place. This means the file itself remains in place, permissions and all, but there will be a duration while you're saving that it is a mix of old and new contents. Text editors tend to do this, often whilst saving the old contents as a separate file in case something goes wrong.
There are tools to manage the side effects too, such as versioned filesystems, file locking, and even libraries prepared for parallel changes (metakit comes to mind). Most of the time we'll be using tools that are already around, like sed -i.
In order to delete or alter a line, you have to "shift" everything after it. For example, consider these two files:
bir bir 100 2 bytes 0-14
iki iki 200 2 bytes 15-29
eray alakese 100 5 bytes 30-49
john doe 2000 10 bytes 50-67
and
bir bir 100 2 bytes 0-14
iki iki 200 2 bytes 15-29
john doe 2000 10 bytes 30-57 <-- byte offsets have changed
This is certainly possible to do, but it's pretty complicated to support in general (you'd have to do a lot of seeks and tells). The more usual approach is to effectively copy the file: you read in from your input-file and print everything out to an output-file, making the modifications you need. (For example, to "delete" a line, you simply don't print that line.) Then, at the end, after closing both files, you "rename" the output-file to overwrite the input-file. This is the approach that command-line utilities such as sed and perl use when instructed to modify a file "in-place".
The usual thing to do is to read all of the file and write all of it back to a temporary file, then delete the original and rename the temporary.
/* pseudo-code!! */
fopen();
while (fscanf(source, ...)) {
/* massage data */
fprintf(temporary, ...);
}
fclose();
remove(source);
rename(temporary, source);
The way I usually handle something like this is to write a function that can "read in" your data and store it to some structure. Then a function to write data from the structure to a file.
This way you can just manipulate the data in an array. This also makes your program more extensible to doing things like sorting, or extra math that you couldnt have done by just writing over the top of the file.
e.g. try writing a function that can read in to a struct like:
struct Client
{
char name[255];
double owes;
double paid;
}
What you then do make an array of these structures and manipulate those.
You'll learn a lot about structs, dynamic memory allocation, and you'll no doubt run in to some interesting issues that will help you learn.
My advice is to also skip C and go for C++... learning this stuff using iostreams instead of the *printf/*scanf functions and vectors is probably going to be better for you in the long run

C - Reading multiple files

just had a general question about how to approach a certain problem I'm facing. I'm fairly new to C so bear with me here. Say I have a folder with 1000+ text files, the files are not named in any kind of numbered order, but they are alphabetical. For my problem I have files of stock data, each file is named after the company's respective ticker. I want to write a program that will open each file, read the data find the historical low and compare it to the current price and calculate the percent change, and then print it. Searching and calculating are not a problem, the problem is getting the program to go through and open each file. The only way I can see to attack this is to create a text file containing all of the ticker symbols, having the program read that into an array and then run a loop that first opens the first filename in the array, perform the calculations, print the output, close the file, then loop back around moving to the second element (the next ticker symbol) in the array. This would be fairly simple to set up (I think) but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this? Not really asking for code ( unless there is some amazing function in c that will do this for me ;) ), just some advice from more experienced C programmers.
Thanks :)
Edit: This is on Linux, sorry I forgot to metion that!
Under Linux/Unix (BSD, OS X, POSIX, etc.) you can use opendir / readdir to go through the directory structure. No need to generate static files that need to be updated, when the file system has the information you want. If you only want a sub-set of stocks at a given time, then using glob would be quicker, there is also scandir.
I don't know what Win32 (Windows / Platform SDK) functions are called, if you are developing using Visual C++ as your C compiler. Searching MSDN Library should help you.
Assuming you're running on linux...
ls /path/to/text/files > names.txt
is exactly what you want.
opendir(); on linux.
http://linux.die.net/man/3/opendir
Exemple :
http://snippets.dzone.com/posts/show/5734
In pseudo code it would look like this, I cannot define the code as I'm not 100% sure if this is the correct approach...
for each directory entry
scan the filename
extract the ticker name from the filename
open the file
read the data
create a record consisting of the filename, data.....
close the file
add the record to a list/array...
> sort the list/array into alphabetical order based on
the ticker name in the filename...
You could vary it slightly if you wish, scan the filenames in the directory entries and sort them first by building a record with the filenames first, then go back to the start of the list/array and open each one individually reading the data and putting it into the record then....
Hope this helps,
best regards,
Tom.
There are no functions in standard C that have any notion of a "directory". You will need to use some kind of platform-specific function to do this. For some examples, take a look at this post from Cprogrammnig.com.
Personally, I prefer using the opendir()/readdir() approach as shown in the second example. It works natively under Linux and also on Windows if you are using Cygwin.
Approach 1) I would just have a specific directory in which I have ONLY these files containing the ticker data and nothing else. I would then use the C readdir API to list all files in the directory and iterate over each one performing the data processing that you require. Which ticker the file applies to is determined only by the filename.
Pros: Easy to code
Cons: It really depends where the files are stored and where they come from.
Approach 2) Change the file format so the ticker files start with a magic code identifying that this is a ticker file, and a string containing the name. As before use readdir to iterate through all files in the folder and open each file, ensure that the magic number is set and read the ticker name from the file, and process the data as before
Pros: More flexible than before. Filename needn't reflect name of ticker
Cons: Harder to code, file format may be fixed.
but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this?
I have solved the exact same problem a while back, albeit for personal uses :)
What I did was to use the OS shell commands to generate a list of those files and redirected the output to a text file and had my program run through them.
On UNIX, there's the handy glob function:
glob_t results;
memset(&results, 0, sizeof(results));
glob("*.txt", 0, NULL, &results);
for (i = 0; i < results.gl_pathc; i++)
printf("%s\n", results.gl_pathv[i]);
globfree(&results);
On Linux or a related system, you could use the fts library. It's designed for traversing file hierarchies: man fts,
or even something as simple as readdir
If on Windows, you can use their Directory Management API's. More specifically, the FindFirstFile function, used with wildcards, in conjunction with FindNextFile

Resources