How can I open an existing file in Xcode in C? - c

I have created a file called mahmoud.txt in the direceotry: /Users/mahmoudhamra/Desktop/C language/
I want to open it in Xcode.
I created the directory and the name of the file into a string each.
Then I concatenated the file name to the directory and tried to open it to read it but it always gives me an error: "Thread 1: signal SIGBART".
Can someone help me please?
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char * argv[]) {
FILE *inFile;
char fileName[13];
printf("enter file name: ");
scanf("%s",fileName);
char new[40]="/Users/mahmoudhamra/Desktop/C language/";
strcat(new, fileName);
inFile=fopen("new", "r");
if (inFile== NULL) {
printf("file %s was not opened!\n", fileName);
printf("check that the file exists!\n");
exit(1);
}
else
printf("the files has successfully been opened!\n");
return 0;
}

First of all this
char new[40]="/Users/mahmoudhamra/Desktop/C language/";
should be at least
char new[41]="/Users/mahmoudhamra/Desktop/C language/";
to leave space for null terminator. A C-string is an array of chars with a null-terminator (0x00, '\0', 0) as last char.
Best would be:
char new[]="/Users/mahmoudhamra/Desktop/C language/";
BTW your problem is that you have no space to add filename chars, so at least you should define it as
char path_and_file[128] = {0};
strncpy(path_and_file, "/Users/mahmoudhamra/Desktop/C language/", sizeof(path_and_file)-1);
If you want to learn something about dynamic allocation you can:
char *directory = "/Users/mahmoudhamra/Desktop/C language/";
char *path_and_file = malloc(strlen(directory)+1);
if (path_and_file != NULL)
{
strcpy(path_and_file, directory);
printf("enter file name: ");
scanf("%s",fileName);
path_and_file = realloc(path_and_file,strlen(directory)+strlen(filename)+1);
if (path_and_file != NULL)
{
strcat(path_and_file, filename);
// YOUR STUFF
}
}
free(path_and_file);
Another way with dynamic allocation is using strdup to create your first string:
char *path_and_file = strdup("/Users/mahmoudhamra/Desktop/C language/");
EDIT
Last thing, as #visibleman pointed out, the call to fopen have to be changed to
inFile=fopen(new, "r");
or according to my examples:
inFile=fopen(path_and_file, "r");

The issue is almost certainly the size of the new character array as it does not have the capacity to hold the complete filename and will cause a stack overflow:
char new[40]="/Users/mahmoudhamra/Desktop/C language/";
strcat(new, fileName);
Change the 40 to 1024:
char new[1024] = ...;

Related

Ho to copy text from one file to another in C?

I am writing a basic program to copy text to another text file. But in the console window after entering the filename from where text should be taken, the program ends and does not go further. How can I solve this problem?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char filename1, filename2;
FILE *infile;
FILE *outfile;
printf("Enter a data file name:");
scanf("%s", filename1);
infile = fopen("filename1", "r");
printf("Enter a input file name:");
scanf("%s", filename2);
outfile = fopen("filename2", "w");
if (infile == NULL || outfile == NULL) {
printf("Problem in opening files");
exit(0);
}
printf("files opened successfully");
char characters;
do {
characters = getc(infile);
fprintf(outfile,"%s", characters);
printf("%s", characters);
} while (!feof(infile));
fclose(infile);
fclose(outfile);
return 0;
}
There are a few problems with your program:
You are using char variables to hold names of files. These variables should be char arrays or pointers to the first char of some allocated memory.
fopen("filename2", "w") seems wrong. Although, the first argument should be a char *, you are not reading / writing the files you just asked the user to enter.
fprintf(outfile,"%s",characters) - You are using %s to print characters. This will invoke UB.
char characters - The last character of a file, the EOF character is guaranteed to fit in an int. The characters variable should be declared as an int so that it can hold the EOF character.
Here is the program that works:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char filename1[10], filename2[10];
FILE *infile;
FILE *outfile;
printf("Enter a data file name:");
scanf("%s",filename1);
infile = fopen(filename1, "r");
printf("Enter a input file name:");
scanf("%s",filename2);
outfile = fopen(filename2, "w");
if (infile==NULL || outfile==NULL) {
printf("Problem in opening files");
exit(0);
}
printf("files opened successfully");
int characters;
/*do {
characters=getc(infile);
fprintf(outfile,"%s",characters);
printf("%s",characters);
} while(!feof(infile));
*/
while ((characters = getc(infile)) != EOF) {
fprintf(outfile, "%c", characters);
printf("%c", characters);
}
fclose(infile);
fclose(outfile);
return 0;
}
There are a number of issues.
char filename1, filename2;
This only allows filename1 and filename2 to hold a single char - not a C string. You need to reserve memory as a char array. Like:
char filename1[64], filename2[64]; // Allow 63 chars for file name
Then
scanf("%s",filename1);
is really bad as it allows the user to overflow your input buffers. Consider using fgets or at least do:
scanf("%63s",filename1); // Limit user input to 63 chars as the buffer is 64
// The "last" char is for the string termination
Then the loop:
First, characters shall be int so that you can check for EOF. Further, check directly on getc instead of using feof. And don't use %s for printing a single char to the output file - use %c. Like
int characters;
while(1) {
characters=getc(infile);
if (characters == EOF) break; // Break (aka jump out of the loop) on
// end-of-file or errors
fprintf(outfile,"%c",characters); // %c instead of %s
// or use: putc(characters, outfile)
// instead of fprintf
printf("%s",characters);
}

Weird input from a file using fscanf()

My main objective here is to make use of fscanf() to take in each word from my file and store it into an array location. As it stands, I loop through the file setting each word to a location in wordList[]. I can print out the values as they are put into the array and each seems to be placed correctly. But after the loop, when I attempt to print only one of the values (simply checking that everything went as it should) I get a weird output. When printing the string contained in wordList[5], it prints the first character of every word after location [5], and prints the last word that was collected.
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void readFile (FILE *fPtr, char *fileName) {
FILE *newFilePtr;
char wordList[1000];
int i = 0;
newFilePtr = fopen(strcat(fileName, ".out"), "w"); // Blank document created under same file name, but with ".out"
while(fscanf(fPtr, "%s", &wordList[i]) == 1) { // Read in strings from main file into wordList
printf("%s\n", &wordList[i]);
++i;
if (i > 10) // KEEP OUTPUT SHORT FOR STACK OVERFLOW QUESTION
break;
}
printf("%s\n", &wordList[5]); // PRINTS WILD VALUE AT POSITION 5
fclose(newFilePtr);
}
int main (int argc, char *argv[]) {
int lineSize;
char *fileName = argv[2]; // Store name of file for future operations
FILE *fPtr;
if (argc != 3) {
fprintf(stderr, "%s", "ERROR: Incorrect arguments. Please input a line size and a file.\n");
return;
}
lineSize = atol(argv[1]); // Convert string to it's integer equivalent
if (lineSize < 25 || lineSize > 100) {
fprintf(stderr, "%s", "ERROR: Line size not within range.\n");
return;
}
if (fPtr = fopen(fileName, "r")) { // If the file exists, open it for reading
readFile(fPtr, fileName);
puts("FILE OPENED SUCCESS");
fclose(fPtr);
} else {
fprintf(stderr, "%s", "ERROR: File could not be opened.\n");
return;
}
return;
}
And my current output (constrained to just the first 10 values to keep it short):
Mason–Dixon
Line
(or
Mason
and
Dixon's
Line)
was
surveyed
between
1763
DLwsb1763 // Should print "Dixon's" (the string at location 5)
FILE OPENED SUCCESS
The creation of the new file at line 11 is for later use when the file is formatted. For now, i'm only concerned with properly scanning in the values from the original file.

Converting commandline argument to string in C

I am new to programming. I want to take one commandline argument which is a filename and open that particular file and copy the contents to another file. I don't know how to convert the commandline argument to a string or file pointer. I checked strcpy and std::string which I found online but it didn't work. Please help me. I have pasted my code below
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
char *inp;
strcpy(inp,argv[1]);
FILE *fp;
char str[5];
//printf("Enter the file name:");
//scanf("%s",fname);
if ((fp= fopen(inp, "r")) == NULL) {
printf("cannot open file");
exit(1);
}
FILE *fp1;
fp1=fopen("out.txt","w+");
while(!feof(fp)) {
fgets(str,4,fp);
printf("%s",str);
fprintf(fp1,"%s",str);
}
fclose(fp);
fclose(fp1);
}
Why not char *inp = argv[1];?
Or better yet:
fp = fopen(argv[1], "r");
The problem with your code is this:
char *inp;
strcpy(inp,argv[1]);
You're copying argv[1] into inp, but you have no idea what inp points to. If you really want to go that route, you have to allocate memory for inp.
char *inp = malloc(strlen(argv[1]) + 1); /* allocate enough for the string and null-terminator */
strcpy(inp,argv[1]); /* copy the contents */
Just remember to free() afterwards.
P.S. Never use while(!feof(fp)). Just use while(fgets(str,4,fp)).
See this question for more info.

Write an output file with a user defined name in C

I am new to C and am trying to define an output filename before the program runs. I am getting a Bus error
Here is my code:
#include <stdio.h>
int main (int argc, const char * argv[]) {
char fname[128];
printf("Enter the file name\n");
scanf("%123s",fname);
strcat("/Users/user/Desktop/learn/", fname);
strcat(fname, ".txt");
FILE *fp;
fp=fopen(fname,"a");
fprintf(fp, "Testing... OK I think it worked\n");
return 0;
}
You didn't #include <string.h> for strcat.
The first argument to strcat must be a pointer, not a string literal.
strcat itself isn't safe, use strncat instead.
Don't forget to check the result of scanf and fopen.
And close fp when you're done with it.
The signature of main should be int main(int argc, char * argv[]).
The use of scanf is also generally discouraged, use fscanf & sscanf instead.
You are using a string literal as the destination pointer in the first call to strcat. so you are concatonating "/Users/user/Desktop/learn/" with fname and storing the result where ever "/Users/user/Desktop/learn/" was stored, which might not even be writable.
That's not how strcat() works.
I see two approaches:
Use fname correctly, together with the file name inputting:
char fname[128];
strcpy(fname, "/Users/user/Desktop/learn/"); // ok as long as you don't make the 128 too small
char * input = fname + strlen(fname); // now points after the final /
printf("Enter the file name\n");
scanf("%123s", input); // the 123 is probably not correct
strncat(fname, ".txt", sizeof fname);
and use it.
Currently, this approach is still suffering from the fact that input is limited to 123 bytes, which might be too large, so better forget it for now. It is just for getting the idea.
Maybe fgets() might be better:
fgets(input, sizeof(fname)-strlen(fname), stdin);
Use command line parameters, which would be my favourite approach:
// first check if argc is >= 2, i. e. if the caller has supplied an argument
char fname[128];
strcpy(fname, "/Users/user/Desktop/learn/");
strncat(fname, argv[1], sizeof fname);
strncat(fname, ".txt", sizeof fname);
Try this, this is worked for me..
http://cboard.cprogramming.com/c-programming/124576-whats-mean-char*-const*-argv.html
#include <stdio.h>
#include <string.h>
int main (int argc, const char*const* argv[])
{
char fname[128];
char path[] = "/home/abc/test/";
printf("Enter the file name\n");
scanf("%123s",fname);
strcat(fname,".txt");
strcat(path,fname);
FILE *fp;
fp=fopen(path,"a");
fprintf(fp, "Testing... OK I think it worked\n");
fclose(fp);
return 0;
}
Thanks for everyone's comments. This was working code:
#include <stdio.h>
#include <string.h>
int main (int argc, const char*const* argv[])
{
char fname[128];
strcpy(fname, "/Users/user/Desktop/learn/");
char * input = fname + strlen(fname);
printf("Enter the file name\n");
scanf("%s", input);
strncat(fname, ".txt", sizeof fname);
printf("The output pathway and file will be called %s\n", fname);
FILE *fp;
fp=fopen(fname,"a");
fprintf(fp, "Testing... OK I think it worked\n");
fclose(fp);
return 0;
}

Subtract from an array of char a number of characters

I can't seem to work it out. I am using a .c code that opens a file and reads each line. I would like to save in char*substr 4 characters from the line 9 inside the txt file. The line 5 contains
name=Me She; I would like to have in char*substr just Meli.Need help. THX
Here is the c code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
char str[128];
char str1[128];
if((fp = fopen("/home/folder/file.txt", "r"))==NULL) {
printf("Cannot open file.\n");
exit(1);
}
int lin=0;
while(!feof(fp)) {
if(fgets(str, 126, fp))
printf("%s", str);
if (lin==8)
{
char *c= (char *) malloc(sizeof(char)*strlen(str)+1);
c= strndup(str, strlen(str)-5);?? not working?!!!
printf("d is:",c);
}
lin=lin+1;
}
fclose(fp);
return 0;
}
Your printf is wrong. change it to printf("d is %s\n",c);.
By the way, strdup allocate the memory needed, so you don't have to allocate it yourself. (In fact, you have a memory leak).
You're calling malloc() and then directly overwriting its result with that of calling strndup(), this leaks memory.
Also, the logic in the strndup() call looks wrong. If you want to skip the first 5 characters, you should have str + 5.
If you have strdup(), use:
if (lin==9)
{
char *name = strdup(str + 5);
printf("name is: '%s'\n", name != NULL ? name : "(failed)");
}
Then you should probably break out of the loop. Also note that the pointer name goes out of scope, so it's not available to code outside the loop for instance.

Resources