Cant read file text file in C - c

Hello i got a problem im trying to solve problem and learn how the learning from files works .I did this code by tutorial and when i execute instead of learning my file and write on console something like 1 4 6 5 1 etc.. its just spam only 0 0 0 0 0 0 0 and then repeat
If you would say me where is the problem it will be good thanks for ur time :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UNUSED(__ARG__) ((void)__ARG__)
int main(int argc, char** argv)
{
UNUSED(argc);
UNUSED(argv);
int i = 0;
FILE* x =fopen("cisla.txt","r");
fscanf(x,"%d",&i);
while (!feof (x))
{
printf("%d",i);
fscanf(x,"%d",&i);
}
fclose(x);
return 0;
}

Whatever tutorial this is, throw it out.
First, you need to check whether your file operations succeeded, otherwise the program will blindly continue along. Likely the fopen failed. It returns NULL on failure so you can check for that and get an error message with perror.
FILE *x = fopen("cisla.txt","r");
if( x == NULL ) {
perror("Could not open the file");
exit(1);
}
Then, as others have mentioned, you don't check for end of file. Instead do the IO operation and check whether it succeeded or failed. In this case, fscanf returns the number of matched items which should be 1.
while ( fscanf(x, "%d", &i) == 1 ) {
printf("%d",i);
}
Note that the scanf family is fraught with gotchas. But you'll get to them later.
Finally, that UNUSED stuff is very clever and totally unnecessary. Just declare main with no arguments. This is perfectly valid.
int main() {

Related

How do i get this to properly exit the program?

So i am trying to get this program to simply exit but i can seem to get it to work.
i tried a lot of things. one thing i found odd as well is if i made x = 0 in the while loop it would immediately exit the program so i had to make it x !=0. i dont understand what that is so if you can answer that as well that would be nice.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char a[256];
int x = 0;
while (x != 0) {
int y = strcmp(fgets(a, 256, stdin), "exit");
if (y==0) {
exit(0);
}
else {
printf("Line read:%s\n",a);
}
}
return 0;
}
so it should output right now something like this(i am also running this in a linux terminal):
//input://
hello
//output://
Line read: hello
//(program stays open for more inputs)//
//input//
exit
//(the program now closes in the terminal and you return to directory)//
The keyboard input contains a new line at the end. Change "exit" to "exit\n" in call to strcmp.

Not working properly. What am I missing?

the program is still very empty and "naked" because im just trying to get the logic out of the way before I actually start making functions. For some reason, whatever my argv[1] is, it always prints "The help message". What am I missing? I have a bad feeling about that for statement, but I dont know whats wrong with it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void help()
{
printf("The help message\n");
exit(1);
}
void a()
{
printf("The a screen\n");
exit(1);
}
int main(int argc, char *argv[])
{
char recognised_commands[3] = {help(), a()};
int i;
if (argc != 2)
{
fprintf(stderr, "usage of sake: \"sake [option(s)]\"\nFor a full listing of all available commands type \"-help\" or \"--help\"\n\n");
exit(1);
}
for (i = recognised_commands[0]; i != recognised_commands; i++)
{
printf(argv[1]);
}
}
Edit 1: djikay: Fixed the -1 to 0,
Ricky: How do I correct the help() and the a() to only call the one the user inputs after the program name (EX: sake -a)? I also fixed the exit(0). Thanks
The line:
char recognised_commands[3] = {help(), a()};
causes both help and a to be called. help is called first, and it prints out the help message & exits the program.
char recognised_commands[3] = {help(), a()};
This line is definitely your issue. help() and a() are both being called, thus exiting your program.
Why are you trying to assign those function return values there? Both of the functions are void in return type, meaning they won't return anything anyways.
On a side note, calling exit() with 0 as the argument means your program exited without errors. I'd exit with 1 if it's because of an error (or even better, EXIT_SUCCESS and EXIT_FAILURE, respectively).

Process exited with return value 3221225477

i am writing this code:
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
int i;
fp = fopen("keimeno.txt","r");
fscanf(fp,"%d",i);
printf("%d\n",i);
fclose(fp);
return 0;
}
and the file contains:
2
Yiannis Ioannou 356
3
Today
10347
If
345
And then none
1542
John Smith 743
2
My story
3940
Feedback
682
END
When I try to run it, it exits me value 3221225477 instead of printing the number 2..
Can anyone explain why?
When you scan a number, you need to pass the address of the variable where you want to store the result:
fscanf(fp,"%d",&i);
where you have
fscanf(fp,"%d",i);
^ missing the & sign!
Your compiler really ought to have warned you - do you enable warnings when you compile?
What is happening here is that the fscanf function writes to the location given (in your case, it writes to whatever location is pointed to by the value of i, instead of writing to the location of i) . This can corrupt your memory in all kinds of nasty ways - resulting, in your case, in the program "running" for considerable time before crashing.
As #Brandin pointed out, there is a further problem with your code (although it's less likely to be the source of your problem). When you attempt to open a file, you should ALWAYS check that you succeeded. You do this with something like this:
#include <assert.h>
// at the top of the program
// attempt to open the file:
fp = fopen("keimeno.txt","r");
// and check whether you succeeded:
assert(fp != NULL); // this says "check fp is not NULL. Otherwise, quit."
Alternatively, you can make things a bit prettier with:
const char *fileName = "keimeno.txt";
const char *mode = "r";
if((fp=fopen(fileName, mode))==NULL) {
printf("cannot open file %s\n", fileName);
return -1;
}
It is almost always a good idea to put "hard wired values" near the start of your program, rather than embedding them in a function call.

file NULL not being forgotten by loop - C

I'm trying to check a directory for a file. I've done that properly. But I'm having trouble for exceptions--> when the file is not there. Here's what I am wanting to do: I 'd like to check for the file, if it exists, then exit the loop. If the file does not exist, then sleep. After sleeping for 3 seconds, check for the file again. Repeat until the file is found then return to main() and print "Hello everyone".
Currently, if the file is missing and i put the file into this directory while the program is running, it never recognizes the new file until i stop the program then start it back up. I want the program to check for the file again after sleep.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <unistd.h>
#define MYFILE "/Users/stackoverflow/Documents/fileabc123"
int checkfile() {
FILE *pFile;
pFile = fopen(MYFILE,"r");
char file_string[40];
int repeat = 0;
while( repeat < 1) {
if (pFile!=NULL) {
fgets (file_string,36,pFile);
fclose (pFile);
printf("%s\n", file_string);
repeat = 1 ;
}
if (pFile ==NULL) {
printf("Machine cannot read system file. \n");
sleep(3);
}
}
}
int main (int argc, char ** argv) {
checkfile();
printf("Hello everyone\n");
return 0;
}
You need to put the fopen in the loop.
if ((pFile = fopen(MYFILE, "r")) != NULL) {
// read it
}
else {
printf("Failed opening");
}
The error is in the loop.
you simply aren't trying to open the file again :)
this give you 2 error:
1. if you put the file it is not seen, as the program does not try to open it
2. if the file is present, you read it, then you close it, leaving an INVALID file descriptr but that is NOT null
this mean next loop you will try to read an invalid file descriptor. It is like reading/writing value with a overflow index from an array, or from a free() pointer.
You will almost always have the right value.. until that ram is reallocated.
so:
1. you have to try to open a file, until you get a valid file descriptor.
2. close will not change pointer value. It simply can't, think about it.
if you whant to change the value of somthing, you have to give it's address. A pointer is the adress of somthing. So File* is pointing to a File, but if you want to change the address pointed by File*, you need it's address (&pFile), just like a scanf :)

execute less with execv?

I have the following c code. I want to display my file with less by calling execv()
however the following seems never work. The program terminates and noting pop out.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void){
int pid;
if(pid=fork()>0){
//read in from stdin and pass to pipe
}else if(pid==0){
//read from pipe
//write to out.txt
//everything up to here works fine
char* para[]={"less","/Desktop/out.txt"};
execv("/bin/less",para);
}
return 0;
}
(The original code contained execv("bin/less", para);.) Unless the current directory is the root directory, /, or unless there is a program less in the subdirectory ./bin/less, then one of your problems is that you have a probable typo in the name of the executable. That assumes the program is /bin/less and not /usr/bin/less. You might even use execvp() to do a PATH-based search for the program.
There's an additional problem: you need to include a null pointer to mark the end of the argument list.
Finally, you can print an error message after the execv() returns. The mere fact that it returns tells you it failed.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pid;
if ((pid = fork()) != 0)
{
// read in from stdin and pass to pipe
// Need to test for fork() error here too
}
else
{
// read from pipe
// write to out.txt
// everything up to here works fine
char *para[] = { "/bin/less", "Desktop/out.txt", 0 };
execv(para[0], para);
fprintf(stderr, "Failed to execute %s\n", para[0]);
exit(1);
}
return 0;
}
Or:
char *para[] = { "less", "Desktop/out.txt", 0 };
execvp(para[0], para);
fprintf(stderr, "Failed to execute %s\n", para[0]);
The remarks in the code about pipes are puzzling since there is no sign of pipes other than in the comments. As it stands, less will read the file it is told to read. Note that less will not paginate its output if the output is not going to a terminal. Since we can see no I/O redirection, we have to assume, then, that less will ignore anything the program tries to write to it, and will not send any data back to the program.
char* para[]={"less","/Desktop/out.txt"};
execv("/bin/less",para);
How does execv know when to stop reading parameters?
I think if you'd put code in there to handle execv() returning an error you'd have found this. You're also not testing for errors from fork().

Resources