I could use some help passing this file pointer to a thread to have the thread write to an output file. Currently the file is not being written to at all and I am not getting any errors and working.
void *ThreadTwo(void *param){
FILE *outputFile = param;
// Condition for even
if (r == 0) {
fprintf(outputFile, "%d\n", globalValue);
fprintf(outputFile, "%d\n", globalValue);
printf("twice becase it is even\n");
}
else {
fprintf(outputFile, "%d\n", globalValue);
printf("Once because it is odd\n");
}
}
pthread_exit(NULL);
}
int main() {
FILE *outputFile;
outputFile = fopen("hw3.out", "w");
pthread_create(&th[1], NULL, ThreadTwo, &outputFile);
fclose(outputFile);
return 0;
}
Related
Hi I have a C programme that is basacally suppose to simulate the pipe function in linux and write the amount of bytes that are read in a .txt file so
./a.out cat test : grep -v le : wc -l
The problem that I'm trying to figure out is
Why is the same amount of bytes written in the file since I know each process returns a different amount ?
This piece of code is executed in the parent and is trying to count the amount of bytes of each output with a read syscall and writes the output in a write syscall in the next process so that the next process can use the output as his input.
So let's say I have these pipes a | b | c
This code will read the output of a and write it in b so that b can use it as it's input and so on.
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
char str[4096];
int count=0;
int nbChar=0;
while(1){
count=read(apipe[i][0],str,sizeof(str));
nbChar+=count;
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
}else if(count==0)break;
}
char *leInput=(char*)malloc(nbChar*sizeof(char));
strncpy(leInput,str,nbChar);
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
Each time through the while(1) loop you're read into the beginning of str, not where you left off in the previous iteration. So you're overwriting the previous read with the next read.
You should copy incrementally to leInput each time through the loop. You can then use realloc() to grow it to accomodate the new input, and you can use leInput + nbChar to copy after the place where you finished the previous time.
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
int nbChar=0;
char *leInput = NULL;
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
leInput = realloc((nbChar + count)*sizeof(char));
memcpy(leInput + nbChar, str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
Alternatively you could just write to the next pipe in the inner loop, without collectiong everything into leInput:
for (int i = 1; i < processes-1; i++) {
int nbChar = 0;
close(apipe[i][1]);
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
write(apipe[i+1][1], str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
close(apipe[i+1][1])
}
I want to create a function that, given a string filename, creates the file called filename.PID inside the ./pid directory.
#define DEBUG 1
//PRINT_DEBUG just print the string in stderr
int CreatePidFile(char *filename){
if(DEBUG){
DEBUG_PRINT("CreatePidFile: start\n");
}
char *path = "./pid/";
char *post = ".PID";
FILE *pidfile;
char *pathfilename;
int N=strlen(path)+strlen(filename)+strlen(post)+1;
if((pathfilename=(char *)malloc(N*sizeof(char)))==NULL){
return -3;
}
strcpy(pathfilename, path);
strcat(pathfilename, filename);
strcat(pathfilename, post);
pathfilename[N-1]='\0'; //just to be sure that it has the final string char
if((pidfile = fopen(pathfilename, "w"))==NULL){
if(DEBUG){
DEBUG_PRINT("CreatePidFile: impossible to create il file\n");
}
free(pathfilename);
return -1;
}
int pid=getpid();
if((fwrite((void *)&pid, sizeof(int), 1, pidfile))==0){
if(DEBUG){
DEBUG_PRINT("CreatePidFile: impossible to write pid in pidfile\n");
}
fclose(pidfile);
free(pathfilename);
return -2;
}
fclose(pidfile);
free(pathfilename);
if(DEBUG){
DEBUG_PRINT("CreatePidFile: end\n");
}
return 0;
}
The main I use is:
int main(){
printf("create pid: start\n");
char *filepid = "test_pid_file";
if((CreatePidFile(filepid))!=0){
printf("file not created\n");
}
else{
printf("test_utility: file is created\n");
}
return 0;
}
At the end of the program, the file is created but is a binary file.
I want a text file.
Well, you do a binary write of the pid:
fwrite((void *)&pid, sizeof(int), 1, pidfile)
If you want text, just use fprintf:
fprintf(pidfile, "%d", (int)pid);
If I write
char ar[100];
strcpy(ar, "I am in child\n");
write(fd, ar, strlen(ar))
It will copy "I am in child" to file located in fd using open function.
But how to write
printf("you got %d points\n",dice);
to another file in C? dice is an integer.
You should use fprintf().
#include <stdio.h>
int main(void) {
int dice = 0;
FILE* fp = fopen("your_file_name.txt", "w");
if (fp == NULL) {
perror("fopen");
return 1;
}
fprintf(fp, "you got %d points\n", dice);
fclose(fp);
return 0;
}
I'd like to write a program that compares two files and writes every byte in file one that is different from file two into a third file. I want to compare the files byte by byte and write any differing single bytes to the third file. I'm not very familiar with file I/O. Can someone give me an example program that accomplishes this task?
This is what I have so far:
int main(int argc, char *argv[]) {
int file1, file2, file1size, file2size;
// int difference1, difference2;
char buf;
if (argc != 3){
fprintf(stderr, "Usage %s <file1> <file2>", argv[0]);
exit(1);
}
if ((file1 = open(argv[1], 0400)) < 0) { //read permission for user on file source
fprintf(stderr, "Can't open source");
exit(1);
}
if ((file2 = open(argv[2], 0400)) < 0) { //read permission for user on file source
fprintf(stderr, "Can't open source");
exit(1);
}
file1size = lseek(file1, (off_t) 0, SEEK_END);
printf("File 1's size is %d\n", file1size);
file2size = lseek(file2, (off_t) 0, SEEK_END);
printf("File 2's size is %d\n", file2size);
}
I'm not sure how to compare file1 and file2's bytes and then write the differences to another file.
This is close to what you are looking for.
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *file1 = fopen(argv[1], "r");
FILE *file2 = fopen(argv[2], "r");
int i;
for(i = 0; !feof(file1) || !feof(file2); i++) {
int byte1 = getc(file1);
int byte2 = getc(file2);
if(byte1 != byte2) {
printf("%d %d %d\n", i, byte1, byte2);
}
}
return 0;
}
It takes the two files as command line arguments and compares the two byte-by-byte. If two bytes are different, it printf the character #, and the ASCII values of the two characters. -1 means EOF was already reached.
You'll have to (understand and) adapt this to the output format you want. (I'm assuming this is homework.)
feof tests for end-of-file.
getc gets the next character (byte) from the file. It is -1 if the end of the file has been reached.
And you seem already to know what printf does.
This does what you want, compiles, and runs,
#include <stdio.h>
int main(int argc, char *argv[])
{
int offset;
int argi=1;
int ch1, ch2;
FILE *fh1, *fh2, *fh3=stdout;
FILE *fh4=stdout;
if( argc<3 ) {
printf("usage: diff <file> <file> { <outfile> }\n"); return(1);
}
if(argi<argc) {
if(!(fh1 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(2);
}
}
if(++argi<argc) {
if(!(fh2 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(3);
}
}
if(++argi<argc) {
if(!(fh3 = fopen(argv[argi], "w+"))) {
printf("cannot open %s\n",argv[argi]); return(4);
}
}
if(++argi<argc) {
//duplicate output to a second file?
if(!(fh4 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(3);
}
}
for(offset = 0; (!feof(fh1)) && (!feof(fh2)); offset++)
{
ch1=ch2='-';
if(!feof(fh1)) ch1 = getc(fh1);
if(!feof(fh2)) ch2 = getc(fh2);
if(ch1 != ch2) {
fprintf(fh3,"%d:%c %c\n", offset, ch1, ch2);
//additional file here
}
else {
fprintf(fh3,"%c\n", ch1);
//additional file here
}
}
return 0;
}
More typically, you would read entire lines using fgets, and strcmp to compare the lines. Here is how,
char str1[1024], str2[1024];
...
for(offset = 0; (!feof(fh1)) && (!feof(fh2)); offset++)
{
strcpy(str1,"-");strcpy(str2,"-");
if(!feof(fh1)) fgets(str1,sizeof(str1),fh1);
if(!feof(fh2)) fgets(str2,sizeof(str1),fh2);
if(strcmp(str1,str2)!=0)
fprintf(fh3,"%d:%s %s", offset, str1, str2);
else
fprintf(fh3,"%c", str1);
}
Code that I am running now:
int main(int argc, char *argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError;
LPSTR DirSpec;
size_t length_of_arg;
int i,j;
char cd[256],schar[500];
FILE *fp;
DirSpec = (LPSTR) malloc (BUFSIZE);
// Check for command-line parameter; otherwise, print usage.
if(argc != 2)
{
printf("Usage: Test <dir>\n");
return 2;
}
// Check that the input is not larger than allowed.
//scanf("%s",argv[1]);
StringCbLength(argv[1], BUFSIZE, &length_of_arg);
if (length_of_arg > (BUFSIZE - 2))
{
printf("Input directory is too large.\n");
return 3;
}
printf ("Target directory is %s.\n", argv[1]);
StringCbCopyN (DirSpec, BUFSIZE, argv[1], length_of_arg+1);
StringCbCatN (DirSpec, BUFSIZE, "\\namefile.b11", 18);
hFind = FindFirstFile(DirSpec, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("Invalid file handle. Error is %u.\n", GetLastError());
return (-1);
}
else
{
printf ("First file name is %s.\n", FindFileData.cFileName);
fp=fopen(DirSpec,"rb");
for(i=0;i< 8;i++)
{
schar[i]= fgetc(fp);//get each character from file
}
if ( i > 7 )
{
cd[i]=schar[6]*65336+schar[5]*256+schar[4];
printf("%d",cd[i]);
}
// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
{
printf ("Next file name is %s.\n", FindFileData.cFileName);
}
dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
printf ("FindNextFile error. Error is %u.\n", dwError);
return (-1);
}
}
free(DirSpec);
getchar();
return (0);
}
This is working fine. If I concatinate the file name directly by using StringCbCatN().
But for every file I need to change the file name.which I don't want. Is it possible to print the file with file extension?