I understand, there are thousands of problems like this, but I haven't managed to find the solution to my issue. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","R");
FILE *outFile=fopen("I:\\Test\main2.cpp", "W");
if (inputFile==NULL) {
printf("Unable to locate source file");
_getch();
return 1;
}
int c;
int inSingleLine=0;
int inMultiLine=0;
int d=fgetc(inputFile);
while(c=fgetc(inputFile)!=EOF){
if (d==EOF) break;
if((c=='/') && (d=='*')) inMultiLine=1;
if ((c='*') && (d=='/')) inMultiLine=0;
if((c=='/')&& (d=='/')) inSingleLine=1;
if (c='\n') inSingleLine=0;
if (!inSingleLine && !inMultiLine) {
putc(c,outFile);
}
d=getc(inputFile);
}
// This is a test string
fclose(inputFile);
fclose(outFile);
/* And this is not a test
Actually not
*/
return 0;
}
No matter what I do, whether I put main.cpp to the same folder with the exe file and make it FILE *inputFile=fopen("main.cpp","R"); or specify an absolute path, I get "Unable to locate source file" all the time.
Please help!
The mode strings for read and write mode are "r" and "w", not "R" and "W". Using an invalid mode is probably what's causing fopen to fail.
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","R"); <-- This results in the string "I:\Testain.cpp"
...
Make sure you use two "\" symbols (escape both back-slashes), and use lower-case "w" and "r":
FILE *inputFile=fopen("I:\\Test\\main.cpp","r");
As above, you must "escape" a backslash with a double one. You should always check the return value from fopen() and then you can obtain a message based on errno. When I tried the following with a lower-case "r" I got a compiler warning about the invalid escape sequence \m but the program was well behaved.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","r");
printf("After trying to open\n");
if (inputFile == NULL)
printf ("%s\n", strerror(errno));
else
fclose(inputFile);
return 0;
}
I got:
After trying to open
No such file or directory
But when I tried it with an upper-case "R" the program hung (MSVC), I don't know why.
Related
It's my first exercise about Files and I have to write some code so that if I write a word in the console, it gets printed in the file. The program ends if I input the word "fine" (it's Italian for end). It seems like the file is opened and closed correctly, the program reads the inserted chars, but nonetheless, the file remains blank.
I tried opening the file in various modes, I tried printing how many chars were read, I even tried deleting the file (but it actually does't exit even if I added exit(1).
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main() {
FILE * fp;
char s[64];
if ((fp = fopen("prova.txt", "r+")) == NULL) {
printf("Error.\n");
exit(1);
}
do {
scanf("%s", s);
if (strcmp("fine", s) != 0) {
fprintf(fp, "%s ", s);
}
} while (strcmp("fine", s) != 0);
fclose (fp);
return 0;
}
It should save all the words in a text file, but it remains blank.
Your program looks OK. Most likely, you are checking the wrong file.
An educated guess: you are using some IDE. If this is the case, the file is created, but is created somewhere else. To be sure, print the working directory (man getcwd) somewhere in the beginning of your program, and look for the file there.
you have to use "w" to open a new file with write priviledges
change
if ((fp = fopen("prova.txt", "r+")) == NULL) {
with
if ((fp = fopen("prova.txt", "w+")) == NULL) {
EDIT: Maybe i didn't explained myself, r+ will fail if the file doesn't exist, changing it works for me
How do you make a file, but only if it doesn't already exist? Like.. I want to read a text file, but if it doesn't exist, I want to create one with some default text.
I can create the file with the default text easy enough. And I can append or overwrite it if it already exists.
But if it already contains some text, I want to READ FROM it. Not WRITE TO it. Like you might do with a dot file or configuration file, to set a default configuration in the event the file is missing.
This is quite simple with Python, but I'm trying to make the transition to C, and It's more challenging than I'd anticipated.
So my function basically looks something like this so far. The text is just a placeholder for whatever the real text might be.
main() {
FILE *fp;
fp = fopen("./filename.txt", "w");
fprintf(fp, "some default text\n");
fclose(fp);
}
So just to clarify: If ./file.txt already exists, it shouldn't be written to. It should be read from.
When I say "read from", it could be printed to stdout, or stored in an array for instance, but that's probably beyond the scope of the question.
Considering your example there are two main mistakes:
You don't check the result of fopen thus you don't know whether your file has been successfully opened (here is the key to the answer).
printf function prints directrly to stdout and you have to use fprintf one for printing to your configuration file.
I propose the following: try to fopen your configuration file (e.g. ./filename.txt) for r and check the result of this call. Upon successful completion fopen return a FILE pointer to your existing configuration file. If the file doesn't exist fopen returns NULL and errno is set to ENOENT. In this case you can create a new configuration file and write a default config into it.
Please see man 3 section for the corresponding docs.
UPD:
Here is PoC for the proposal
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
FILE *fp = fopen(".rc", "r");
if (!fp)
switch (errno) {
case ENOENT:
fprintf(stderr, "No config found, creating the default one\n");
fp = fopen(".rc", "w");
if (!fp) {
perror("Failed to create default config: ");
return EXIT_FAILURE;
}
/* write default config here */
break;
default:
perror("Failed to open existing config: ");
return EXIT_FAILURE;
}
/* read existing config here */
return EXIT_SUCCESS;
}
Use stat before opening your file. If the stat is successful then the file exists, if it is not, check for ENOENT in errno.
Example
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
struct stat file_infos;
char file_path[] = "/whatever"
if (stat(file_path, &file_infos) != 0)
{
if (errno == ENOENT)
{
// Do whatever when the file wasn't found
}
else
{
// Error accessing the file, check the errno for more infos
}
}
else
{
// File exists, do whatever you like with it.
}
}
Enjoy :)
I am trying to 1) Find all files in a directory and display them, 2) Open all found files and read data from them (characters) 3) Output the read data to the screen or a new file.
This is done in C Language and you will see below my current code. The problem that I am running into is that: I can find all the files in my directory and print them to the screen just fine (point 1 above), but when I try to open the found files and read data (characters) from them (point 2 above), I get a segmentation fault.
If I comment out the fscanf(entry_file, "%s", files); line below, but leave the entry_file = fopen(in_file->d_name, "r"); line, it compiles okay and writes the files to the screen. I also tried indexing the fscanf line with the int i (not shown below) and produced the same segmentation fault.
So, how can I read data from these found files? Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
int main()
{
DIR* dir;
FILE *entry_file;
struct dirent *in_file;
char files[1000];
int i;
dir = opendir("/Users/tcn/data");
if(dir==NULL){
printf("Error! Unable to read directory");
exit(1);
}
while( (in_file=readdir(dir)) != NULL) {
if (!strcmp (in_file->d_name, "."))
continue;
if (!strcmp (in_file->d_name, ".."))
continue;
printf("%s\n", in_file->d_name);
entry_file = fopen(in_file->d_name, "r");
fscanf(entry_file, "%s", files);
}
closedir(dir);
fclose(entry_file);
return 0;
}
Seeing as you are correctly checking for NULL against dir and in_file before using them, the only other thing that could possibly be causing this is entry_file being null. Check it before using it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
int main()
{
DIR* dir;
FILE *entry_file;
struct dirent *in_file;
char files[1000];
int i;
dir = opendir("/Users/tcn/data");
if(dir==NULL) {
printf("Error! Unable to read directory");
exit(1);
}
while((in_file=readdir(dir)) != NULL) {
if (!strcmp (in_file->d_name, "."))
continue;
if (!strcmp (in_file->d_name, ".."))
continue;
printf("%s\n", in_file->d_name);
entry_file = fopen(in_file->d_name, "r");
if (entry_file != NULL) {
fscanf(entry_file, "%s", files);
/* whatever you want to do with files */
fclose(entry_file);
}
}
closedir(dir);
return 0;
}
Note also that, as multiple other users have commented, you should close entry_file within the loop.
The two most likely causes of the crash are not checking the return value of fopen – then either the fscanf or the fclose may crash when attempting to use entry_file when it's NULL – and the potential overflow of files.
Another problem which does not cause a crash is that the in_file->d_name does not contain the full path, but only the name of the file. So if you are testing the code inside /Users/tcn/data then it will appear to work, but it will fail elsewhere. Either prefix the filename with /Users/tcn/data/ or operate only on the current directory (.).
Fixes:
if ((entry_file = fopen(in_file->d_name, "r"))) {
(void) printf("%s\n", in_file->d_name);
if (fgets(files, sizeof files, entry_file)) { // or `while`?
// do something with `files`, it will be overwritten for next file
}
(void) fclose(entry_file);
}
And remove the other fclose(entry_file) from the end of the code.
Also note that if you use this code with an arbitrary directory, it might contain pipes and/or device nodes that will hang forever when you attempt to read them.
You will need a function with a loop using fread() to replace the fscanf line, and do a hex dump. For one thing, you don't know if the files are text files or binary files. For another, the segfault could be coming from reading a binary file that contains no newline into char files[1000]; And even if the files are all text files, you cannot predict that your "generous" 1000 length is enough to hold the first line of text.
My first post :), am starting out with C language as basic learning step into programming arena. I am using following code which reads string from text file, makes directory with that string name and opens a file for writing in that created directory. But am not able to create a file inside directory made, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
int main()
{
char file_name[25], cwd[100];
FILE *fp, *op;
fp = fopen("myfile.txt", "r");
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
if (_getcwd(cwd,sizeof(cwd)) != 0)
{
fprintf(stdout, "Your dir name: %s\\%s\n", cwd,file_name);
op = fopen("cwd\\file_name\\mynewfile.txt","w");
fclose(op);
}
fclose(fp);
return 0;
}
What you need is to store the file name (with the path) in a c-string before opening. What you are opening is cwd\file_name\mynewfile.txt. I doubt that your directory is named cwd.
A sample could could be:
char file_path[150];
sprintf(file_path, "%s\\%s\\mynewfile.txt", cwd, file_name);
op = fopen(file_path,"w");
use
#include <sys/stat.h>
#include <sys/types.h>
instead of
#include <direct.h>
and modify
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
I see you are using the return values. That is a good start for a beginner. You can refine your error messages by including "errno.h". Instead of printing your own error messages call
printf("%s", strerror(errno));
You get more precise error messages that way.
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
You’re actually passing the string literals “cwd” and “file_name” as part of the path of the file, when I think you actually mean to put the contents of the variables with those names in there. You will probably have to piece together a string for the path. Try looking into strcat()
http://www.cplusplus.com/reference/cstring/strcat/
I'm trying to make a program to open a file, called "write.txt".
#include <stdio.h>
main() {
FILE *fp;
fp = fopen("write.txt", "w");
return 0;
}
Should this work? Because it returns nothing.
Other than an old variant of main, there's not really much wrong with that code. It should, barring errors, create the file.
However, since you're not checking the return value from fopen, you may get an error of some sort and not know about it.
I'd start with:
#include <stdio.h>
#include <errno.h>
int main (void) {
FILE *fp;
fp = fopen ("write.txt","w");
if (fp == NULL) {
printf ("File not created okay, errno = %d\n", errno);
return 1;
}
//fprintf (fp, "Hello, there.\n"); // if you want something in the file.
fclose (fp);
printf ("File created okay\n");
return 0;
}
If you're adamant that the file isn't being created but the above code says it is, then you may be a victim of the dreaded "IDE is working in a different directory from what you think" syndrome :-)
Some IDEs (such as Visual Studio) will actually run your code while they're in a directory like <solution-name>\bin or <solution-name>\debug. You can find out by putting:
system ("cd"); // for Windows
system ("pwd") // for UNIXy systems
in to your code to see where it's running. That's where a file will be created if you specify a relative path line "write.txt". Otherwise, you can specify an absolute path to ensure it tries to create it at a specific point in the file system.
What did you expect it to 'return' - it opens a file, on most platforms creating one if it doesn't exist.
You should probably fclose(fp) the file at the end.
I think you want to print the contents of file write.txt. (Assume it contains characters).
#include <stdio.h>
int main()
{
FILE *fp,char ch;
fp=fopen("write.txt","r");
if(fp==NULL)
{
printf("Some problem in opening the file");
exit(0);
}
else
{
while((ch=fgetc(fp))!=EOF)
{
printf("%c",ch);
}
}
fclose(fp);
return 0;
}
I think you should study some more fundamentals in C before you start attempting to work with files. A return means some data is passed back to the calling code from the called function.In this case you return 0 at the end of your program. You did not do anything with your FILE pointer except cause a new file to be created...