Word Count, Segmentation Fault - C - c

I'm trying to run a program that finds the word count for a file. Every time I compile the program it gives me a Segmentation Fault(Core Dumped). Can't figure out why.
#include <stdio.h>
int main(int argc, char* argv[]){
int wc = 1;
FILE *input = fopen(argv[1],"r");
char c = fgetc(input);
while(c != EOF){
if(c == ' '){
wc++;
}
else
c = fgetc(input);
}
fclose(input);
printf("Word Count = %d", wc);
return 0;
}

You're probably segfaulting because you're not passing in a file name on the command line. When you do that, argv[1] is NULL, so fopen is dereferencing a NULL pointer.
You pass the file name to your program on the command line like this:
./my_program file_to_test
To prevent the core dump, you should check that an argument was passed in by checking the value of argc. You should also check the return value of fopen to ensure the file was opened:
if (argc < 2) {
printf("no file name given");
exit(1);
}
FILE *input = fopen(argv[1],"r");
if (input == NULL) {
perror("fopen failed");
exit(1);
}
Then you have another problem:
if(c == ' '){
wc++;
}
else
c = fgetc(input);
When you find a space character, you don't attempt to read the next character. So c doesn't change once a space is read, leading to an infinite loop.
You need to get rid of the else and always call fgetc:
if(c == ' '){
wc++;
}
c = fgetc(input);
Also, the fgetc function returns an int (actually an unsigned char cast to an int), so you should declare c as an int. Otherwise, checking it against EOF can fail.

Related

How to take first row from this list of text?

I have a list of columns containing text but I just to fetch first upper row from this list. How to do that?
#include <stdio.h>
int main()
{
FILE *fr;
char c;
fr = fopen("prog.txt", "r");
while( c != EOF)
{
c = fgetc(fr); /* read from file*/
printf("%c",c); /* display on screen*/
}
fclose(fr);
return 0;
}
Your stop condition is EOF, everything will be read to the end of the file, what you need is to read till newline character is found, furthermore EOF (-1) should be compared with int type.
You'll need something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr;
int c;
if(!(fr = fopen("prog.txt", "r"))){ //check file opening
perror("File error");
return EXIT_FAILURE;
}
while ((c = fgetc(fr)) != EOF && c != '\n')
{
printf("%c",c); /* display on screen*/
}
fclose(fr);
return EXIT_SUCCESS;
}
This is respecting your code reading the line char by char, you also have the library functions that allow you to read whole line, like fgets() for a portable piece of code, or getline() if you are not on Windows, alternatively download a portable version, and, of course you can make your own like this one or this one.
For whatever it's worth, here's an example that uses getline
#include <stdio.h>
int main()
{
FILE *fr;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if (!(fr = fopen("prog.txt", "r"))) {
perror("Unable to open file");
return 1;
}
nread = getline(&line, &len, fr);
printf("line: %s, nread: %ld\n", line, nread);
fclose(fr);
return 0;
}
Some notes:
getline() can automatically allocate your read buffer, if you wish.
getline() returns the end of line delimiter. You can always strip it off, if you don't want it.
It's ALWAYS a good idea to check the status of I/O calls like "fopen()".
just replace EOF as '\n'(new line char). Than your code will read until reaching the new line. Here is what it looks like:
#include <stdio.h>
int main()
{
FILE *fr;
char c = ' ';
fr = fopen("prog.txt", "r");
while(c != EOF && c != '\n')
{
c = fgetc(fr); /* read from file*/
if(c != EOF){
printf("%c",c); /* display on screen*/
}
}
fclose(fr);
return 0;
}
I have not tested it yet but probably work. Please let me know if there is some problem with the code i will edit it.
Edit1:char c; in line 5 is initialized as ' ' for dealing with UB.
Edit2:adding condition (c != EOF) to while loop in line 7, for not giving reason to infinite loop.
Edit3:adding if statement to line 10 for not printing EOF which can be reason for odd results.

How does following statement produce spaces?

What my program "upper" trying to do is making letters upper case. It gets a file from the commmand line as argv; then reads it afterwards it makes them uppercase.
An example: "i wonder if it works" in the example.txt file. In command line:
C:\Users\...>upper example.txt
I WONDER IF IT WORKS
This was the code I used first:
int main (int argc, char *argv[]){
FILE * fp;
int ch;
if ((fp = fopen (argv[1] , "r+")) == NULL) {
fprintf (stderr , "Can not be opened.");
exit(EXIT_FAILURE);
}
while((ch = getc(fp)) != EOF){
if (isalpha(ch))
putchar(toupper(ch));
else
putchar(' ');
}
fclose(fp);
return 0;
}
It works but I saw a more concise version which doesn't need the else statement.
while((ch = getc(fp)) != EOF){
putchar(toupper(ch));
}
And it puts the spaces between each word too. How is this possible?
From the documentation
int toupper(int c);
Converts c to its uppercase equivalent if c is a lowercase letter and has an uppercase equivalent. If no such conversion is possible, the value returned is c unchanged.

getc function produce segfault

Program:
#include<stdio.h>
#include<string.h>
char *f_gets(char *s, int n, FILE *iop)
{
int c=0;
char *cs;
cs = s;
while (--n > 0 && (c = getc(iop)) != EOF)
{
if ((*cs++ = c) == '\n')
break;
}
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
main(int argc, char *argv[])
{
FILE *fp1,*fp2;
char s2[100],s1[100];
if (argc <= 2 )
printf("2 argument needed \n");
else
if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL)
printf("cat: can't open The file\n");
else
{
while(1)
{
f_gets(s1,100,fp1); // 1st iteration
f_gets(s2,100,fp2); // 2nd iteration
if(!strcmp(s1,s2))
printf("%s %s",s1,s2);
}
fclose(fp1);
fclose(fp2);
}
}
Output:
$ ./a.out a b
Segmentation fault (core dumped)
$
In the above program, the segfault occurs when we call the f_gets at second time. Even I twice check the program it is hard to
find the problem. Does any one explain why it produce the problem .
Your second file is not open at the time when you make the call.
The problem is that you are calling fopen from the path with short circuiting:
if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL)
Because of a mistake in your code, when fp1 opens fine, fp2 will always remain closed. This is because (fp1=fopen(argv[1],"r"))== NULL will evaluate to 0, and ensure that (fp2=fopen(argv[2],"r"))==NULL will never be called.
You could fix this by replacing && with ||, but a better approach would be opening one file at a time.
if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL)
means, "if the program failed to open both fp1 and fp2". You could solve this by using || instead. But preferably don't write long and complex expressions, since they add nothing but an increased chance of writing bugs.
Instead, do this:
fp1=fopen(argv[1],"r");
if(fp1 == NULL)
{
// error handling
}
fp2=fopen(argv[2],"r");
if(fp2 == NULL)
{
fclose(fp1);
// error handling
}
And as a bonus: just because we re-wrote the program into something readable, we now also spotted a second bug. In case the program opened fp1 but failed to open fp2, it never closed fp1 before aborting.

Reading each char line by line in C

I was looking for a solution on how to read char by char on each line from a txt file and I found one, but I don't get some parts of the code. This is it:
#include <stdio.h>
#include <stdlib.h>
void handle_line(char *line) {
printf("%s", line);
}
int main(int argc, char *argv[]) {
int size = 1024, pos;
int c;
char *buffer = (char *)malloc(size);
FILE *f = fopen("myfile.txt", "r");
if(f) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(f);
if(c != EOF) buffer[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length - leave room for 0
size *=2;
buffer = (char*)realloc(buffer, size);
}
}while(c != EOF && c != '\n');
buffer[pos] = 0;
// line is now in buffer
handle_line(buffer);
} while(c != EOF);
fclose(f);
}
free(buffer);
return 0;
}
It was written by someone from here, but I can't reply 'cause I need more points lol. The parts I don't understand are:
if(c != EOF) buffer[pos++] = (char)c;
What does buffer[pos++] do? does it actually increase the variable "pos"? also, why does it start at 1 instead of 0? (pos starts at 0).
I can't really get track of the variable "pos", and I don't know why here buffer[pos] is 0:
buffer[pos] = 0;
The way I read the code is:
declare the size of the buffer that contains every char of every line (I mean, buffer is just free'd at the end, so it keeps the information on every line right?), then declare the other variables and alloc the memory of the buffer.
Open the file myfile.txt, and if it's not null, make pos = 0, then make "c" to store the first character of the file (now the function points to the next char), then if c != EOF meaning the end of file is not reached, save the character "c" in the position 1 of the buffer (I get confused here, why 1 and not 0). Then realloc twice as memory as before if needed. Do that for every character in the line untile you reach EOF or a \n. Now make buffer[pos] = 0, I dont know what value "pos" has, and I assume he makes buffer[pos] = 0 to indicate the end of the line? idk. Print the line, do that until you reach the end of the file. Close the file, free the memory on buffer.
Help! thanks.
fgetc(fp) - Reads the next character from the specified input stream (fp) and advances the associated file position indicator (you do not need to). If successful, the function will return the character read; otherwise, the value EOF (-1) is returned.
Here is a very simple example of using fgetc() to read each character of a file (and write it to another file using fputc())
char filename1[]={"c:\\play\\_in.txt"};//change paths as needed
char filename2[]={"c:\\play\\_out.txt"};
int main(void)
{
FILE *fp1 = {0};
FILE *fp2 = {0};
int c=0;
fp1 = fopen(filename1, "r");
if(fp1)
{
fp2 = fopen (filename2, "w");
if(fp2)
{
c = fgetc(fp1);
while(c != EOF)
{
fputc(c, fp2);
c = fgetc(fp1);
}
fclose(fp2);
}
fclose(fp1);
}
return 0;
}

C Program that takes a character and file names as command line arguments and keeps count of that character in each file

I'm fairly new to C and i've been stuck on this problem for a few hours now. Basically I'm trying to develop a program that takes a character and zero of more file names as command-line arguments. If no arguments follow the characters, have the program read the standard input. else, have it open each file in turn and report how many times the character appears in each file to an output file. Here's my code and i'm not very sure if my whole logic is correct for this program. Here's my code so far:
int main(int argc, char *argv[]){
FILE *in = stdin;
FILE *out = stdout;
//FILE *hold;
int j,c, count[NUM] ={0}, total =0;
for(j=1;j<argc;j++){
if(argv[j][0] == '-'){
if(argv[j][1] == 'o'){
if(argv[j][2] == '\0')
out = fopen(argv[j++],"w");
else
out = fopen((argv[j] +2),"w");
}
} else {
in = fopen(argv[j],"r");
}
while((c = fgetc(in)) != EOF){
count[c]++;
total++;
}
if(fclose(in) != 0)
fprintf(stderr,"error in closing file %s\n", argv[1]);
getchar();
return 0;}
I did solve a few other command line argument practices with no problems but this one seems to be a bit harder for my current level in C. Thank you for your help

Resources