fopen() is a directory, what must be changed? - c

im getting the fopen() is a directory and I am unable to locate my error,
it works perfectly with put and fgets. (Code That Works)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) // Use a valid prototype for main
{
char path[256] = "/your/fixed/path/";
size_t len = strlen(path);
puts("Enter a file name:");
// Get the file name leaving room for the path
if (fgets(path + len, sizeof(path) - len, stdin))
{
// Strip the trailing new line
path[strcspn(path, "\n")] = 0;
}
// Nothing to concat
FILE *file = fopen(path, "w");
// Always check the result of fopen
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
// Do your stuff ...
fclose(file);
return 0;
}
I want to use printf and scanf instead of puts and fgets, and when I use the below code I get the reply as fopen() is a directory
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) // Use a valid prototype for main
{
char path[256] = "./casestudy/";
size_t len = strlen(path);
char *bt ="dd.txt";
// Get the file name leaving room for the path
if(path + len, sizeof(path) - len, bt)
{
// Strip the trailing new line
path[strcspn(path, "\n")] = 0;
}
// Nothing to concat
FILE *file = fopen(path, "w");
// Always check the result of fopen
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
// Do your stuff ...
fclose(file);
return 0;
}

You probably want something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) // using valid prototype for main
{
char path[256] = "./casestudy/";
puts("Enter the filename: ");
// Ask for filename from the user
char filename[256];
fgets(filename, sizeof(filename), stdin);
filename[strcspn(filename, "\n")] = 0; // remove trailing \n if any
// concatenate user provided filename to the path
strcat(path, filename);
// now path contains the full path to the file
printf("Full path is \"%s\".", path);
// FILE *f = fopen(path, ....)
// ...
}
Disclaimer: there is no checking for valid input, if the user provides a filename which is too long you'll get a buffer overflow. I let you deal with this as an exercise.

Related

How change the file path/directory where a file created in c program is saved?

im new to C, im trying to save a file created in the c program beginner.c in a directory called casetudy. How can I implement that as fileopen() funtion only accepts 2 arguments. The FILE_NAME also dynamically changes, how can I do both accept dynamically changing files names and a fixed directory path?
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define FILE_NAME "tex.txt"
int main(){
FILE* file_ptr = fopen(FILE_NAME, "w");
fclose(file_ptr);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <unistd.h> you don't need this
#define FILE_NAME "tex.txt"
int main(void) // Use a valid prototype for main
{
char path[256] = {0}; // Buffer for dynamic path
puts("Enter a path:");
// Get the path leaving room for FILE_NAME
if (fgets(path, sizeof(path) - strlen(FILE_NAME), stdin))
{
// Strip the trailing new line
path[strcspn(path, "\n")] = 0;
}
// Concat FILE_NAME
strcat(path, FILE_NAME);
FILE *file = fopen(path, "w");
// Always check the result of fopen
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
// Do your stuff ...
fclose(file);
return 0;
}
what is its the other way round the path is fixed the filename is
dynamic?
char path[256] = "/your/fixed/path/";
size_t len = strlen(path);
puts("Enter a file name:");
// Get the file name leaving room for the path
if (fgets(path + len, sizeof(path) - len, stdin))
{
// Strip the trailing new line
path[strcspn(path, "\n")] = 0;
}
// Nothing to concat
FILE *file = fopen(path, "w");
...

How to replace words in a text file with a user input in C

I want to find a way to replace the word that was found the same with the user input. For instance, the user inputs "er" and then these words come up:
What I want to do is replace the "er" on all of these words with again a user input. for example , the user then writes "el" instead of "er". When this happens, the original file will not change but another file will be created that will save all the changes made. Does anyone have an idea?
#include <stdlib.h>
#include <string.h>
#include<conio.h>
#define MAX 1024
int main(int argc, char* argv[]) {
FILE* myFile = fopen("C:\\Users\\doom\\Desktop\\txtfiles\\singlewords.txt", "r+");
FILE* myFile1 = fopen("C:\\Users\\doom\\Desktop\\txtfiles\\sentences.txt", "r+");
FILE* tempFile = fopen("C:\\Users\\doom\\Desktop\\txtfiles\\singlewordstemp.txt", "w");
char inputWord[MAX];
char inputRepl[MAX];
char lineBuffer[MAX];
char all_lines[MAX];
//char buffer[MAX + 2];
//char* buff_ptr, * find_ptr;
//size_t find_len = strlen(lineBuffer);
if (myFile == NULL)
{
printf("File Does Not Exist \n");
return 1;
}
strcat(all_lines, lineBuffer);
printf("Enter the word \n");
fgets(inputWord, MAX, stdin);
//printf("\nEnter String to replace:");
//scanf("%s", inputRepl);
while (!feof(myFile))
{
char lineBuffer[1024];
fscanf(myFile, "%1024[^\n]\n", lineBuffer);
//printf("%s\n", lineBuffer);
while (fgets(lineBuffer, MAX, myFile)) {
if (strstr( lineBuffer, inputWord))
puts(lineBuffer);
}
}
}

Comparing user input with text in a file

The below code can output what is inside my file. I am trying to find a way to compare if the user input word/character is included in the text file. For instance, if the user writes "r" then, the program finds all the words that have an "r" in the file and output them. After that, I want to replace this word with something, so instead of "r", make it "k". For example, "roadtrip" --> "koadtrip".
The text file has a lot of words line by line , a screenshot of a small part
#define MAX 1024
int main() {
FILE* myFile = fopen("C:\\Users\\Luther\\Desktop\\txtfiles\\words.txt", "r+");
char inputWord[MAX];
char lineBuffer[MAX];
if (myFile1 == NULL)
{
printf("File Does Not Exist \n");
return 1;
}
printf("Enter the word \n");
fgets(inputWord, MAX, stdin);
while (!feof(myFile1))
{
char lineBuffer[1024];
fscanf(myFile1, "%1024[^\n]\n", lineBuffer);
//printf("%s\n", lineBuffer);
while (fgets(lineBuffer, MAX, myFile)) {
if (strstr(lineBuffer, inputWord))
puts(lineBuffer);
}
}
}
I 've managed to make it work and now the program outputs regarding the user input. If a word is the same or part of it is found in the text file, then it prints the word. Look the screenshot below:
Now I am looking for a way to replace the word. For instance, in this specific situation, the word the user inputted is "es" and then all the words that have "es" as a part of them are printed. Is there a way that I can replace for all occasions the "es" and make it "er". Then save the changes in another file without changing anything in the original file.
Here is something to use as a start:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int main (int argc, char *argv[])
{
FILE *fp = fopen(argc > 1 ? argv[1] : "/etc/motd", "r");
char *line = NULL;
char *p = NULL;
char *needle = argv[2];
char *replace = argv[3];
size_t len = 0;
ssize_t read;
assert(fp);
while ((read = getline(&line, &len, fp)) != -1) {
if (line[0] != '#') {
if ((p = strstr(line, needle))) {
printf("%.*s%s%s", (int)(p - line), line, replace, p+strlen(replace));
} else {
printf("%s", line);
}
}
}
free(line);
fclose(fp);
return 0;
}
Note: this may not handle all edge cases. Also writing back to a file or renaming to
original is left as an exercise :)
Some other starting point
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<regex.h>
#include<sys/types.h>
int main (){
//open file
FILE *file_pointer = fopen("./test_txt.txt", "r");
const char* search_for = "3_hau_gbs";
int line_number = 1;
char* line = NULL;
size_t len = 0;
regex_t regex;
int failed = regcomp(&regex, search_for, REG_EXTENDED);
//You are serching bitwise, so you must first semicompile it
if(failed){
regfree(&regex);
} else {
while(getline(&line, &len, file_pointer) != -1){
//go line after line and check if it include the word you
//you are looking for
int match = regexec(&regex, line, 0, NULL, 0);
if(!match){
//when find so output
printf("%d:%s",line_number, line);
}
line_number++;
}
if(line){
free(line);
}
regfree(&regex);
fclose(file_pointer);
}
}

Calling a Perl Script from a C Script, Sorting Text File

I'm making a program that displays a menu and offers to sort a file using multiple different languages. Currently I have a piece of code that will take in a text file, sort it, and output it to a new text file:
# include <stdio.h>
# include <string.h>
#define MAXNAMELEN 100
#define MAXLINELEN 100
#define MAXITEMS 1000
int main(int argc, char ** argv) {
FILE * infile, * outfile;
// Statically allocated -- dastardly!
char name[MAXNAMELEN];
char line[MAXLINELEN];
char lines[MAXITEMS][MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
// No error checking -- ANYWHERE -- dastardly!
infile = fopen(name, "r");
while (fgets(line, sizeof(line), infile)) {
strcpy(lines[items], line);
items++;
}
qsort(lines, items, MAXLINELEN, strcmp);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fputs(lines[i], outfile);
}
fclose(infile);
fclose(outfile);
}
I have the menu part down, but I'm having trouble implementing a way to call a Perl script to sort the file. I want the C program to do the writes to the output file, but the Perl Script to sort it. How can this be achieved? Nasty embedding is what I've found so far..
You can pipe a process with popen and then get the output with fgets:
#include <stdio.h>
#include <stdlib.h>
FILE *popen(const char *command, const char *mode);
int pclose(FILE *stream);
int main(void)
{
FILE *cmd;
char result[1024];
cmd = popen("myperlscript myparams", "r");
if (cmd == NULL) {
perror("popen");
exit(EXIT_FAILURE);
}
while (fgets(result, sizeof(result), cmd)) {
printf("%s", result);
}
pclose(cmd);
return 0;
}

C - why do I get this segfault with my File I/O program?

I'm making a practice program to make a simple alteration to a variable in my Makefile while learning C. I get a segfault whenever I run this program, but I don't know why. I suspect it has something to do with the "r+" fopen mode or my use of fseek(). Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void rewind(FILE *f)
{
long start = 0;
fseek(f, start, SEEK_SET);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("arguments too many or too few. use: setfile <filename> (minus .c extension)\n");
exit(1);
}
FILE *mfile = fopen("Makefile", "r+"); // note to self: r+ is for a file that already exists
FILE *old_mfile = fopen("OLD.Makefile", "r+"); // w+ erases the file and starts in read-write mode with a fresh one
char line[200];
char *fn_ptr;
char *name = argv[1];
while(fgets(line, 199, mfile)) // first create the backup
{
fputs(line , old_mfile); // before changing the line, write it to the backup
}
rewind(mfile); // reset the files to position 0
rewind(old_mfile);
puts("Makefile backed-up as 'OLD.Makefile'");
while(fgets(line, 199, old_mfile)) // now lets loop again and rewrite with the new FNAME
{
if((fn_ptr = (strstr(line, "FNAME= "))))
{
fn_ptr += strlen("FNAME= ");
int i;
for(i = 0; i < strlen(name); i++)
{
*(fn_ptr+i) = *(name+i);
}
*(fn_ptr+i) = '\0';
}
// printf("%s", line); // for debugging
fputs(line , mfile);
}
printf("FNAME is now: '%s'\n", argv[1]);
fclose(mfile);
fclose(old_mfile);
return 0;
}
Check this line again:
FILE *old_mfile = fopen("OLD.Makefile", "r+"); // w+ erases the file and starts in read-write mode with a fresh one
You have the correct mode in the comment, but not in the fopen call.
How to not get the segmentation fault, besides changing the mode? Always check return values! If fopen fails it will return NULL.
Here is a working version. There are several subtle points to note here so I will leave you to examine them one by one by toggling the changes in and out. The man pages for the called functions are probably enough if carefully read.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void rewind(FILE *f)
{
long start = 0;
fseek(f, start, SEEK_SET);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("arguments too many or too few. use: setfile <filename> (minus .c extension)\n");
exit(1);
}
FILE *mfile = fopen("Makefile", "r+"); // note to self: r+ is for a file that already exists
FILE *old_mfile = fopen("OLD.Makefile", "w+"); // w+ erases the file and starts in read-write mode with a fresh one
char line[200];
char *fn_ptr;
char *name = argv[1];
while(fgets(line, 199, mfile)) // first create the backup
{
fputs(line , old_mfile); // before changing the line, write it to the backup
memset(line,0x00,200);
}
rewind(mfile); // reset the files to position 0
rewind(old_mfile);
memset(line,0x00,200);
puts("Makefile backed-up as 'OLD.Makefile'");
fclose(mfile);
mfile = fopen("Makefile", "w");
while(fgets(line, 199, old_mfile)) // now lets loop again and rewrite with the new FNAME
{
if((fn_ptr = strstr(line, "FNAME=")) != NULL)
{
fn_ptr += strlen("FNAME=");
int i;
for(i = 0; i < strlen(name); i++)
{
*(fn_ptr+i) = *(name+i);
}
*(fn_ptr+i) = '\0';
}
// printf("%s", line); // for debugging
fputs(line , mfile);
fputs("\n" , mfile);
memset(line,0x00,200);
}
printf("FNAME is now: '%s'\n", argv[1]);
fclose(mfile);
fclose(old_mfile);
return 0;
}

Resources