I created a function to print the contents of a file:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
where file is a global variable. GDB gives output as follows:
_IO_getc (fp=0x0) at getc.c:39
39 getc.c: No such file or directory.
(gdb) bt
#0 _IO_getc (fp=0x0) at getc.c:39
#1 0x000000000040075e in readFile ()
#2 0x00000000004006d4 in main ()
However, the file is present and I get the SEGFAULT after printing the contents of the file. It might be because the buffer here (c) is small but I am not sure. Also, I don't know how do I fix this even if that were the case. Can anyone suggest how do I proceed?
EDIT
I call the readFile function only once. Here is my calling function:
int main(int argc, char* argv[])
{
char * filename;
filename = argv[1];
readFile(filename);
printf("File Handler: %ld", (long)file);
fclose(file);
return 0;
}
You're passing in a filename that doesn't exist or for some other reason cannot be opened. Get rid of the segfault by checking for errors (you'll need to #include <errno.h> and <string.h> too for this:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
if (file == NULL) {
printf("Cannot open file '%s' : %s\n", filename, strerror(errno));
return;
}
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
Most likely your file is NULL and you are still trying to read it.
I simulated this behaviour (SEG fault) when I deleted this file.
If file exists then your code works fine.
Check what path you are passing.. If you are using single \ try with \\ and see if this works. First \ will work as escape sequence and final path will be send as D:\temp\use.dat to fopen.
readFile("D:\\temp\\user.dat");
Before you do anything with a file, you must ensure that you opened it successfully. This is done by checking that the file pointer received by calling fopen is not NULL.
Once you do this, you read using whatever function you choose until it returns a value that indicates failure to read — a NULL pointer for fgets, 0 or EOF for fscanf, or EOF for fgetc.
In any case, you challenge these return values in two ways. The first way is to check for read errors using ferror. The other way is to check whether the end of the file was reached using feof.
A complete program that should work, based upon your code:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
enum { OPEN_ERROR = 1, READ_ERROR };
enum { PARAM_EXIT = 1, OPEN_EXIT, READ_EXIT };
FILE *file = NULL;
int readFile(char* filename)
{
int c;
file = fopen(filename, "r");
if (file == NULL)
return OPEN_ERROR;
printf("The contents of file '%s' are:\n", filename);
while((c = fgetc(file)) != EOF)
printf("%c", c);
/*
* fgetc returns EOF on end of file and when an error occurs.
* feof is used to determine whether the end of the file was reached.
* Otherwise, we encountered a read error.
*/
if (feof(file))
c = 0;
else
c = READ_ERROR;
return c;
}
int main(int argc, char *argv[])
{
int status = 0;
if (argc == 1) {
fprintf(stderr, "usage: %s file\n", argv[0]);
return PARAM_ERROR;
}
/* Check that <program ""> wasn't used... */
if (argv[1][0] == '\0') {
fprintf(stderr, "error: empty filename detected, exiting. . .\n");
return PARAM_ERROR;
}
switch (readFile(argv[1])) {
case 0:
break;
case OPEN_ERROR:
fprintf(stderr, "error: file open failed - %s\n", strerror(errno));
status = OPEN_EXIT;
break;
case READ_ERROR:
fprintf(stderr, "error: file read failed - %s\n", strerror(errno));
status = READ_EXIT;
break;
default:
fprintf(stderr, "error: unknown error occurred, aborting...\n");
abort();
}
if (file != NULL)
fclose(file);
return status;
}
Of course, normally you would close the file in the same function in which it was opened (e.g. something like filep = openFile(...); readFile(filep); fclose(filep);, except error handling would be used of course).
I am completely changing my answer
Actually, the file that I was reading was open in gedit (which might explain why I was getting "NULL" even after printing the file contents. I closed the file and removed my NULL comparison code and it works perfectly fine.
Ok, from everybody's comments I got to know that you basically get a SEGFAULT when you read the contents of file that has NULL contents. I just made a simple fix in my while loop:
while((c != EOF))
{
printf("%c", c);
c = fgetc(file);
if(c == NULL)
break;
}
Problemo solved! (Although, the compiler gives me a warning of "comparison between pointer and integer".)
Related
I'm trying to open the output_voice_capture.txt but it gives me a segementation fault, not only the file exists but it has read privilege.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fPtr;
char ch;
/*
* Open file in r (read) mode.
*/
printf("Opening file ......\n");
fPtr = fopen("/flash/etc/output_voice_capture.txt", "r");
if(fPtr == NULL)
{
/* Unable to open file hence exit */
printf("Unable to open file.\n");
printf("Please check whether file exists and you have read privilege.\n");
exit(EXIT_FAILURE);
}
/* File open success message */
printf("File opened successfully. Reading file contents character by character.\n");
do
{ printf("Read single character from file ......\n");
/* Read single character from file */
ch = fgetc(fPtr);
/* Print character read code ASCII on console */
printf ("%d \n", ch);
} while(ch != EOF); /* Repeat this if last read character is not EOF */
printf("Closing file ......\n");
fclose(fPtr);
return 0;
}
I am using minicom which contains all the bin that I can use , the problem is that when I use linux terminal and a simple .txt test file the code works just fine.
As Zaboj Campula already said in his comment EOF is defined as an integer of -1. On some systems a char is a value from 0..255, on others from -127..128. To avoid any problems one should use the feof() function (link) to check the end of the stream. This might be the source of your problem due to the different sizes of char and int.
Your code will print "File opened successfully. Reading file contents character by character." for each character read.
Leave functions only at one place: at the end. This makes your code much more readable
When parts of your code depend on something, enclose it with an error check.
Try this code:
int main() {
FILE * fPtr;
char ch;
int result = 0;
printf("Opening file ......\n");
if (!(fPtr = fopen("/flash/etc/output_voice_capture.txt", "r")) {
printf("Unable to open file.\n");
printf("Please check whether file exists and you have read privilege.\n");
result = EXIT_FAILURE;
} else {
printf("File opened successfully. Reading file contents character by character.\n");
while (EOF != (ch = fgetc(fPtr))) {
printf ("%d \n", ch);
}
fclose(fPtr);
}
return result;
}
For example I have a text file includes "I'm having great day!", I want to count each character and word in this file.
in the example "there are 3 a, 1 m" etc.
I'm new at C and know how to open a file, how can find a specific char or word in file but couldn't figure this out. Can you help me pls.
The first thing you need to learn is how to open and process a file one character at a time. You can do this with a program like:
#include <stdio.h>
int main(int argc, char *argv[]) {
// Must provide one argument, the file to process.
if (argc != 2) {
fprintf(stderr, "Usage: myprog <inputFileName>\n");
return 1;
}
// Try to open the file.
FILE *inFile = fopen(argv[1], "r");
if (inFile == NULL) {
fprintf(stderr, "Cannot open '%s'\n", argv[1]);
return 1;
}
// Process file, character by character, until finished.
int ch;
while ((ch = fgetc(inFile)) != EOF) {
putchar(ch); // <accumulate>
}
// Close file and exit.
fclose(inFile);
// <output>
return 0;
}
Then it's a matter of changing the putchar call into whatever you need to do (accumulating character counts) and outputting that information before you exit from the main function.
The following code compiles with no error or warnings, I can also execute the program and it will act as expected in that it will return the error messages at locations it is expected, for example, providing arguments to non-existent files. This lets me know the code is working as far as line 28 (close of the !fpc section)
Meaning there must be an issue from the
register int ch, i;
Down to
return (1);
before
printf("\"%s\"\n",line);\
The program is expected to take command line arguments of the program name itself and two file names, it then opens both of these files, and should then copy strings from the first file up to a max length to the second file while adding " to both the start and end of the string in the new file.
The code I have is
fgetline.c
#include "fgetline.h"
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: enquote filetocopy filetowrite \n");
exit(1);
}
fp = fopen(argv[1], "r");
if (!fp) {
printf("Couldn't open copy file: (%d) %s\n", errno, strerror(errno));
return -1;
}
fpc = fopen(argv[2], "r+");
if (!fpc) {
printf("Couldn't open write file: (%d) %s\n", errno, strerror(errno));
return -1;
}
register int ch, i;
ch = getc(fp);
if (ch == EOF)
return -1;
i = 0;
while (ch != '\n' && ch != EOF && i < max) {
line[i++] = ch;
ch = getc(fp);
}
line[i] = '\0';
while (ch != '\n' && ch != EOF) {
ch = getc(fp);
i++;
}
return(i);
printf("\"%s\"\n",line);
fclose(fp);
fclose(fpc);
return 0;
}
fgetline.h
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int fgetline(FILE *fp, char *line, int max);
FILE *fp, *fpc;
#define max 30
char line[max + 1];
I am compiling with
debian:~/uni/Ass0$ gcc fgetline.c -Wall -o enquote
debian:~/uni/Ass0$ cd /
testing I did was
debian:~/uni/Ass0$ ./enquote
usage: enquote filetocopy filetowrite
debian:~/uni/Ass0$ ./enquote test
usage: enquote filetocopy filetowrite
debian:~/uni/Ass0$ ./enquote test frog
Couldn't open write file: (2) No such file or directory
debian:~/uni/Ass0$ ./enquote monkey frog
Couldn't open copy file: (2) No such file or directory
debian:~/uni/Ass0$ cat test
ting
test
123
tim#debian:~/uni/Ass0$ cat test2
tim#debian:~/uni/Ass0$ ./enquote test test2
tim#debian:~/uni/Ass0$ cat test2
expected result would be when I run ./enquote test test2, would copy
ting
test
123
from test to test2 so it would appear like
"ting"
"test"
"123"
Thanks, not sure how much more info to give.
There are many issues with your code, compiling with all warnings enabled would have spotted some of them:
Declaring global variables in a header file is good practice, but not defining them there. The extern keyword is used for declarations. The definitions belong in the C file. In this case, variables such as fp, fp1, line should be defined as local variables, not global variables.
Output file argv[2] should be open with "w" mode, "r+" is used for updated mode and will fail if the file does not exist. Update mode is very tricky and confusing, avoid using it.
Do not use the register keyword, it is obsolete now as compilers are smart enough to determine how to best use registers.
Your while loops will read just 2 lines from the input file, storing the first into the line array and discarding the second one.
The return (i); statement exits the program, no output is performed, the remaining statements in the function are ignored completely (-Wall might have spotted this error).
You can simplify the problem by considering this: You want to output a " at the beginning of each line and before the '\n' at the end of each line. You do not need to buffer the line in memory, which would impose a limit on line length. Just output the " whenever you start a line and before you end one:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp, *fpc;
int ch, last;
if (argc != 3) {
printf("usage: enquote filetocopy filetowrite\n");
exit(1);
}
fp = fopen(argv[1], "r");
if (!fp) {
fprintf(stderr, "Could not open input file: (%d) %s\n",
errno, strerror(errno));
return 2;
}
fpc = fopen(argv[2], "w");
if (!fpc) {
fprintf(stderr, "Could not open output file: (%d) %s\n",
errno, strerror(errno));
return 2;
}
last = '\n'; // we are at the beginning of a line
while ((ch = fgetc(fp)) != EOF) {
if (last == '\n') {
fputc('"', fpc); // " at the beginning of a line
}
if (ch == '\n') {
fputc('"', fpc); // " at the end of a line
}
fputc(ch, fpc);
last = ch;
}
if (last != '\n') {
// special case: file does not end with a \n
fputc('"', fpc); // " at the end of a line
fputc('\n', fpc); // put a \n at the end of the output file
}
fclose(fp);
fclose(fpc);
return 0;
}
I am trying read a text from file in C but I am getting nothing in command prompt.Here my code is,please help me ...
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *file=NULL;
file = fopen("C:\\Users\\ylmzt_000\\Desktop\\Yeni klasör\\deneme.txt", "r");
if(file != NULL)
{
printf("----------------\n");
printf("content\n");
printf("-----------------\n");
int ch;
while((ch=fgetc(file)) != EOF)
{
putchar(ch);
}
printf("\n");
fclose(file);
}
return 0;
}
If fopen() returns NULL, an error occured. Construct an else part which may contain
fprintf(stderr, "cannot open '%s' (%s)\n", fn, strerror(errno));
where fn contains your filename.
Also see http://linux.die.net/man/3/fopen for further hints.
There is no obvious problem in your code. The problem may be related to the fact that the filename contains non-ASCII characters:
C:\\Users\\ylmzt_000\\Desktop\\Yeni klasör\\deneme.txt
Try renaming the directory with only ASCII characters.
I am getting segmentation fault when i compile my code.
I am not getting what is wrong with my code will be happy if someone can help me.
#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[])
{
FILE *fp;
char fline[100];
char *newline;
int i,count=0,occ=0;
fp=fopen(argv[1],"r");
while(fgets(fline,100,fp)!=NULL)
{
count++;
if(newline=strchr(fline,'\n'))
*newline='\0';
if(strstr(fline,argv[2])!=NULL)
{
printf("%s %d %s",argv[1],count,fline);
occ++;
}
}
printf("\n Occurence= %d",occ);
return 1;
}
See man open and man fopen:
FILE *fp;
...
fp=open(argv[1],"r");
open returns an integer, not a file pointer. Just change that line to
fp=fopen(argv[1],"r");
Note: OP edited this error out of the code in the question, for those who wonder what this is about
Which leads us to (some other minor issues addressed as well - see comments):
+EDIT: point to places where error checking should be done:
#include<stdio.h>
#include<string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
FILE *fp;
char fline[100];
char *newline;
int i, count = 0, occ = 0;
// for starters, ensure that enough arguments were passed:
if (argc < 3) {
printf("Not enough command line parameters given!\n");
return 3;
}
fp = fopen(argv[1], "r");
// fopen will return if something goes wrong. In that case errno will
// contain the error code describing the problem (could be used with
// strerror to produce a user friendly error message
if (fp == NULL) {
printf("File could not be opened, found or whatever, errno is %d\n",errno);
return 3;
}
while (fgets(fline, 100, fp) != NULL) {
count++;
if (newline = strchr(fline, '\n'))
*newline = '\0';
if (strstr(fline, argv[2]) != NULL) {
// you probably want each found line on a separate line,
// so I added \n
printf("%s %d %s\n", argv[1], count, fline);
occ++;
}
}
// it's good practice to end your last print in \n
// that way at least your command prompt stars in the left column
printf("\n Occurence= %d", occ);
return 1;
}
ps: so the error occurs during runtime and not during compile time - this distinction is quite crucial, because hunting down a compiler failure and solving a library usage error require rather different techniques...