To read the content of a file in C - c

I have a C code to read a txt file:
#include <stdio.h>
int main()
{
FILE *pf;
int ii;
int jj;
char *filename;
printf("enter file name");
scanf("%s",filename);
printf("%s",filename);
pf = fopen("filename+.txt", "r");
if(pf==Null)
{
printf("cant open");
}
else
{
fscanf(pf,"%d,%d" ,&ii,&jj );
printf("%d,%d\n" ,ii,jj);
}
fclose(pf);
return 0;
}
Still i get segmentation error.
The input txt file contains
2,3
I get segmentation fault(core dumped) when i run the program as ./readfile input.
What is going wrong here , how can i correct this?

int main(char *) is not a legal signature for main in C. Only
int main(void)
and
int main(int argc, char **argv)
are legal. In your case, you will need the latter.

That is not the correct way to specify arguments to your program. ie you can't do this:
int main(char *filename)
There should have been a compiler error when you compiled your program. The correct definition is:
int main( int argc, char **argv )
Where argv is an array of strings. Try doing this experiment:
int main( int argc, char **argv )
{
int i;
for( i = 0; i < argc; i++ ) {
printf( "arg %d is: \"%s\"\n", argv[i] );
}
return 0;
}
Then, write your program to use the correct argument list as above.
One other point to make is that you should test the return value of fopen. If it is NULL, then you should NOT try to access the file (because it failed to open).

There are many mistakes here.
After calling fopen(), you should check if pf is NULL, because fopen() can fail.
You are trying to open the file of name filename+.txt. Shouldn't you be opening the file which the name was provided as parameter?
Also, the structure of main() should be int main(int argc, char **argv), you cannot do whatever you want about this.
Check if argc > 1, in which case the program was started with parameters, and the file name should've been provided in argv[1].
Update on comments: This is how your code should look like:
int main()
{
char filename[512]; // reserve 512 bytes to receive the file name from input
FILE *pf;
int ii;
int jj;
printf("Enter file name: ");
scanf("%s", filename);
pf = fopen(filename, "r");
if (pf)
{
fscanf(pf,"%d,%d", &ii, &jj);
printf("%d,%d\n", ii, jj);
fclose(pf);
}
else
{
printf("Failed to open file name %s", filename);
}
return 0;
}
You can also do this to get the filename from the parameters:
int main(int argc, char **argv)
{
FILE *pf;
int ii;
int jj;
if (argc > 1)
{
pf = fopen(argv[1], "r");
if (pf)
{
fscanf(pf, "%d,%d", &ii, &jj);
printf("%d,%d\n", ii, jj);
fclose(pf);
}
else
{
printf("Failed to open file name %s", argv[1]);
}
}
else
{
printf("Insuficient parameters");
}
return 0;
}
Or even, if you don't want to pass the file extension:
int main(int argc, char **argv)
{
char *filename;
FILE *pf;
int ii;
int jj;
if (argc > 1)
{
filename = malloc(strlen(argv[1]) + 5); // alloc necessary memory
strcpy(filename, argv[1]);
strcat(filename, ".txt");
pf = fopen(filename, "r");
if (pf)
{
fscanf(pf, "%d,%d", &ii, &jj);
printf("%d,%d\n", ii, jj);
fclose(pf);
}
else
{
printf("Failed to open file name %s", filename);
}
}
else
{
printf("Insuficient parameters");
}
return 0;
}

Related

C program doesn't output anything

This program is supposed to open a text file, then search for given words in argv. It will search for the words line by line and if it finds one of the given words in that line the program should print it.
This the code I wrote for it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int existe_mot_cle(char s[1024], int argc, char *argv[])
{
int test = 0;
for (int i = 2; i < argc; i++)
{
if (strstr(s, argv[i]))
test = 1;
break;
}
return test;
}
int open_file(char *argv[], FILE *fp)
{
fp = fopen(argv[1], "a");
}
int main(int argc, char *argv[])
{
FILE *fp;
char s[1024];
if (!open_file(argv, fp))
return 0;
while (fgets(s, 1024, fp))
{
if (existe_mot_cle(s, argc, argv))
printf("%s", s);
}
fclose(fp);
}
The problem is when I run it, nothing happens and I don't know why. I am new to the C language. Can someone give me the solution and explain it please?
You are breaking the for loop right after the first if statement is executed. You should surround it with curly braces:
int existe_mot_cle(char s[1024], int argc, char *argv[])
{
int test = 0;
for (int i = 2; i < argc; i++)
{
if (strstr(s, argv[i])) {
test = 1;
break;
}
}
return test;
}
You can make it simpler and more generic:
bool existe_mot_cle(char s[1024], size_t size, const char *ss[])
{
for (size_t i = 0; i < size; i++) {
if (strstr(s, ss[i]))
return true;
}
return false;
}
Also, your open_file() should return an int, but it is not returning anything. Better remove it from your code since it serves no purpose:
int main(int argc, const char *argv[])
{
if (argc < 3) {
printf("Usage: %s [file] [words]\n", argv[0]);
return 0;
}
const char *filename = argv[1]; // More meaningful
const char **otherarg = argv + 2;
FILE *fp = fopen(filename, "r");
if (!fp) {
printf("Could not open %s.\n", filename);
return 0;
}
char s[1024];
while (fgets(s, sizeof s, fp))
{
if (existe_mot_cle(s, argc-2, otherarg)) // I'm using the second "simpler" version
printf("%s", s);
}
fclose(fp);
}

File I/O Uninitialised Variable Problem - C Program

I have the following code and when I try to run it, I get the following warning:
warning: variable 'myfile' is uninitialized when used here [-Wuninitialized]
myfile = fetch_file(myfile, argc, argv);
note: initialize the variable 'myfile' to silence this warning
FILE *myfile;
I have been trying to find out how to fix the warning but haven't been successful.
#include <stdio.h>
#include <stdlib.h>
#define LINE_SIZE 300
FILE * fetch_file(FILE *myfile, int argc, char *argv[1])
{
if (argc == 1)
{
printf("Error, not enough commandline arguments.");
exit(0);
}
myfile = fopen (argv[1], "r");
if (myfile == NULL)
{
printf("\nNo file named %s was found.", argv[1]);
exit(0);
}
else
{
printf("%s was successfully opened", argv[1]);
}
return myfile;
}
void print_file(FILE *the_file, char *line, int size)
{
int count = 0;
while (fgets(line, size, the_file) != NULL)
{
printf("%s", line);
count++;
}
fclose(the_file);
printf("\nThere are %d lines\n", count);
}
int main (int argc, char *argv[])
{
FILE *myfile;
char line[LINE_SIZE];
myfile = fetch_file(--> myfile <-- , argc, argv); <----------- (warning)
print_file(myfile, line, LINE_SIZE);
return 0;
}
Ps: I'm fairly new to asking questions on this website, so if there is any way I can improve my questions and code, feel free to criticise me...
You want this:
FILE *fetch_file(int argc, char *argv[1])
{
if (argc == 1)
{
printf("Error, not enough commandline arguments.");
exit(0);
}
FILE *myfile = fopen (argv[1], "r");
...
}
int main (int argc, char *argv[])
{
FILE *myfile;
char line[LINE_SIZE];
myfile = fetch_file(argc, argv);
...
}
It is pointless to pass the myfile parameter to fetch_file.
The reason for the warning is that you pass an uninitialized value to a function:
This simple code reproduces this exact problem:
int foo(int bar)
{
bar = 2;
return bar * 2;
}
int main (int argc, char *argv[])
{
int kwork; // kwork is not initialized
foo(kwork); // here you pass an uninitialized value
// which the foo function cannot use in a useful manner
}

Seg fault from within my print function after reading in a file in c

I have an unknown segfault within my print function when I call it in main and I can't see what the obvious fix is. I have put printf's throughout the program and it doesn't print 'here4' making me think it's due to my print function, or when I call it in main.
I want to read a dictionary file into an array of strings.
Here is a snippet of the code:
Any ideas would be greatly appreciated, thanks.
#define PRIME 1009
void fileRead(int argc, char **argv)
void printTable(int arrayLength, char **table);
int main(int argc, char **argv)
{
char **table;
FILE *fp;
int i, arrayLength = PRIME;
/* Initial memory allocation */
table = (char**)malloc(PRIME*sizeof(char));
fileRead(argc, argv);
printf("here3\n");
for(i = 0; i < arrayLength; i++) {
printTable(arrayLength,table);
}
printf("here4\n");
return 0;
}
void fileRead(int argc, char **argv)
{
FILE *fp;
char *word;
int arrayLength = PRIME;
word = calloc(MAXCHAR, sizeof(char));
fp = fopen (argv[1], "r");
printf("here1\n");
/*read in grid and move along a cell each time */
while (fscanf(fp, "%s", word)!= EOF) {
if (argc != (2)) {
fprintf(stderr, "Cannot open file, %s\n Try again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
}
if(fp == NULL) {
fprintf(stderr, "Cannot open file, %s\n Try again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
return;
}
if (fp == NULL) {
fprintf(stderr, "Error opening file, try file name dictionary.txt\n");
exit(EXIT_FAILURE);
}
}
printf("here2\n");
fclose(fp);
return;
}
void printTable(int arrayLength, char **table)
{
int i;
for(i = 0; i < arrayLength; i++) {
printf("%s\n", table[i]);
}
printf("\n");
}
Let me summarize your code:
you allocate uninitialized memory for table
You call a function fileRead():
Allocate some memory for word
read the file
Do nothing with the data read.
fileRead() does nothing useful: It does not return anything, it doesn't touch table, is vulnerable to a buffer overflow of word and leaves the memory leak of word behind.
And then you printf the unchanged and uninitialized content of table
try this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRIME 1009
#define MAXCHAR 256
char **fileRead(FILE *fp, int *len);
void printTable(int arrayLength, char **table);
int main(int argc, char **argv){
if (argc != 2) {
fprintf(stderr, "Need dictionary file argument.\nTry again e.g. %s dictionary.txt\n" , argv[0]);
exit(EXIT_FAILURE);
}
FILE *fp = fopen (argv[1], "r");
if(fp == NULL) {
fprintf(stderr, "Cannot open file, %s\nTry again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
exit(EXIT_FAILURE);
}
int arrayLength = PRIME;
char **table = fileRead(fp, &arrayLength);//fclose(fp) inside this
printTable(arrayLength, table);
for(int i = 0; i < arrayLength; ++i)
free(table[i]);
free(table);
return 0;
}
char **fileRead(FILE *fp, int *len){
char *word = calloc(MAXCHAR, sizeof(char));
char **table = malloc(*len * sizeof(char*));
int i = 0;
while (i < *len && fscanf(fp, "%s", word) != EOF){
table[i] = malloc(strlen(word)+1);
strcpy(table[i++], word);
}
fclose(fp);
*len = i;
free(word);
return table;
}
void printTable(int arrayLength, char **table){
int i;
for(i = 0; i < arrayLength; i++) {
printf("%s\n", table[i]);
}
printf("\n");
}

Arguments to open file

I want to open a file using the arguments when executing it, for example:
./Project 123.txt
I can make this work to some extent, but if I try to pass the arguments into a function, and then call the function, something is not working quite right.
Here is the function I have, which will read the lines from a text file:
int numeroLinhas(){
int ch;
FILE *fp;
int linhas=0;
fp = fopen("123.txt","r");
while( ( ch = fgetc(fp) ) != EOF ){
if(ch=='\n'){
linhas++;
}
}
fclose(fp);
fprintf(stats, "linhas: %d\n", linhas);
}
int main(int argc, char *argv[]){
FILE *fp;
fp = fopen(argv[1],"r");
numeroLinhas();
}
So, I would like to know how can I pass the argv[] has an argument into my numeroLinhas() function, so that I don't have to call the name of the file at all during the coding, just when executing.
The problem is that you have hard-coded the file name to open. Modify your function to take an argument, a string naming the file.
Then just pass the correct argv entry as the argument to the function, after checking the number of arguments to the program first.
Pass the name of the file to the function that counts the lines in the file:
#include <stdio.h>
void numeroLinhas(const char *filename)
{
int ch;
int linhas = 0;
FILE *fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return;
}
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
linhas++;
}
fclose(fp);
fprintf(stats, "linhas: %d no %s\n", linhas, filename);
}
int main (int argc, char *argv[])
{
for (int i = 1; i < argc; i++)
numeroLinhas(argv[i]);
return 0;
}
Error check fopen() calls; they fail. Handle the int returned by fgetc() correctly. Change the function to return void since there isn't a return. Report errors on standard error. Include file name in the outputs (error and routine). Invoke the function on all arguments provided. Don't say anything if no arguments are provided — or add if (argc < 2) { fprintf(stderr, "Usage: %s file [...]\n", argv[0]); return 1; } before the loop in main().
Sorry about mixed English/Portugese messages.
int numeroLinhas(char *filename){
char ch;
FILE *fp;
int linhas=0;
fp = fopen(filename,"r");
while( ( ch = fgetc(fp) ) != EOF ){
if(ch=='\n'){
linhas++;
}
}
fclose(fp);
fprintf(stats, "linhas: %d\n", linhas);
}
int main (int argc, char *argv[]){
//should have an if for argc size
char *filename = argv[1];
numeroLinhas(filename);
}

How to redirect more than one text file in c programm

How to redirect more than one text file in c program? For example I have the following C code:
//redirection.c
#include<stdio.h>
main()
{
int x,y;
scanf("%d",&x);
x=x*x;
printf("%d",x);
scanf("%d",&y);
y=x+y;
printf("%d",y);
}
After compiling this code I created two text files text1.txt having the value 8 and text2.txt having the value 6.
When I give input to this program using command line redirection (as redirection<text1.txt), it gives output 64 and does not wait to take another input (and program exits) which I want to give another input from text2.txt.
Is there any solution how can I send another input via text2.txt for second scanf function in the above program?
While giving the input as redirection as like this.
cat a b | ./a.out.
Or else you can use the command line arguments.
#include<stdio.h>
main(int argc, char *argv[])
{
FILE *fp, *fp1;
if ( (fp=fopen(argv[1],"r")) == NULL ){
printf("file cannot be opened\n");
return 1;
}
if (( fp1=fopen(argv[2],"r")) == NULL ){
printf("file cannot be opened\n");
return 1;
}
int x,y;
fscanf(fp,"%d",&x);// If you having only the value in that file
x=x*x;
printf("%d\n",x);
fscanf(fp1,"%d",&y);// If you having only the value in that file
y=x+y;
printf("%d\n",y);
}
you can also use command line arguments:
#include <stdio.h>
#define BUFSIZE 1000
int main(int argc, char *argv[])
{
FILE *fp1 = NULL, *fp2 = NULL;
char buff1[BUFSIZE], buff2[BUFSIZE];
fp1 = fopen(argv[1], "r");
while (fgets(buff1, BUFSIZE - 1, fp1) != NULL)
{
printf("%s\n", buff1);
}
fclose(fp1);
fp2 = fopen(argv[2], "r");
while (fgets(buff2, BUFSIZE - 1, fp2) != NULL)
{
printf("%s\n", buff2);
}
fclose(fp2);
}
here is a more cleaned up version:
#include <stdio.h>
#define BUFSIZE 1000
void print_content(char *file);
int main(int argc, char *argv[])
{
print_content(argv[1]);
print_content(argv[2]);
}
void print_content(char *file){
char buff[BUFSIZE];
FILE *fp = fopen(file, "r");
while (fgets(buff, sizeof(buff), fp) != NULL)
{
printf("%s\n", buff);
}
fclose(fp);
}

Resources