fprintf not working C - c

I'm trying to make a simple program that writes to a .txt file, but this code won't work.
#include <stdio.h>
#include <string.h>
#include "main.h"
int main(int argc, const char * argv[])
{
FILE *f = fopen("text.txt", "w+");
char c[256];
printf("What's your name?\n");
scanf("%s", c);
fflush(f);
if (c!=NULL)
{
printf("not null\n");
int q = fprintf(f, "%s", c);
printf("%d", q);
}
else
{
printf("null\n");
}
printf("Hello, %s\n", c);
fclose(f);
return 0;
}
The printf returns that it's not null, and the int q returns whatever the length of the char is. Why isn't this writing to the file?

the printf returns that it's not null,
Thats because c is not null , since you have scanned your name string into it.
Why isn't this writing to the file?
The program is working fine , on my system.
-- Edit --
FILE *f = fopen("text.txt", "w+");
if (NULL == f)
perror("error opening file\n");
By doing the error handling this way , the exact reason (in your case permissions) , would be displayed,

Turns out I wasn't running with the correct permissions. Stupid mistake on my part.

First off, you've declared c in local scope, so it will never be NULL. If you want to check whether or not the user entered anything, check the length of c after you've scanned in the string:
if (strlen(c) == 0) {
///
}
Second, check whether or not you have permission to write to the current working directory. You should be checking the return value of fopen:
if (!f) {
fprintf(stderr, "Failed to open text.txt for writing\n");
}

Related

read a text file, make some trivial transformation character by character (swapping the case of all letters), write result to text file

I have to read a text file, make some trivial transformation character by character (swapping the case of all letters), write results to the text files. I wrote this code, but it's not working. Please guide me in this regard. Thanks for in Advance
#include <stdio.h>
#include <stdlib.h>
int main() {
char c[1000];
char x[100];
char var;
int i;
FILE *fptr;
if ((fptr = fopen("text.txt", "r")) == NULL) {
printf("Error! opening file");
// Program exits if file pointer returns NULL...
exit(1);
}
// reads text until a newline is encountered...
fscanf(fptr, "%[^\n]", c);
printf("Data from the file:\n%s", c);
// Convert the file to upper case....
for( i=0;i<= strlen(c);i++){
if(c[i]>=65&&c[i]<=90)
c[i]=c[i]+32;
}
fptr = fopen("program.txt","w");
fprintf(fptr,"%[^\n]",c);
fclose(fptr);
return 0;
}
Edit: added #include <stdlib.h>, removed static describing main()
My proposition, based on example of copying a file given at my uni.
I used toupper() from ctype.h, if you don't want to use it you can just add 32 under condition similarly to your solution
Note: there could be char c instead of int c. (In the original version it actually was char; I changed it because if you look at the headers in the docs of all functions dealing with c, they all take/return int, not char; in your version it would matter more as you keep an array, in my program it changes pretty much nothing – int is just my preferred practice).
Note2: I actually never delved into the difference between "w"/"r" (write/read) and "wb"/"rb" (write/read binary). The code seems to work either way.
(I think there is no big difference when the files are text files anyway, for further assurance that both versions work, note that the code uses feof() to handle EOF)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
FILE *from, *to;
int c;//could be char
/* opening the source file */
if ((from = fopen("text.txt", "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen("program.txt", "wb")) == NULL) {
printf("error while opening target file\n");
exit(1);
}
while (!feof(from)) {
c = fgetc(from);
if (ferror(from)) {
printf("error while reading from the source file\n");
exit(1);
}
if (!feof(from)) {//we avoid writing EOF
fputc(toupper(c), to);
if (ferror(to)) {
printf("error while writing to the target file\n");
exit(1);
}
}
}
if (fclose(from) == EOF) {
printf("error while closing...\n");
exit(1);
}
if (fclose(to) == EOF) {
printf("error while closing...\n");
exit(1);
}
return 0;
}
For a version taking arguments from command line (works on windows too) replace the beginning of main with
int main(int argc, char *argv[]) {
FILE *from, *to;
char c;
/* checking the number of arguments in the command line */
if (argc != 3) {
printf("usage: name_of_executable_of_this_main <f1> <f2>\n");//name_of_exe could be copy_to_upper, for example; change adequately
exit(1);
}
/* opening the source file */
if ((from = fopen(argv[1], "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen(argv[2], "wb")) == NULL) {
printf("error while opening the target file\n");
exit(1);
}
I don't know how to code in that language(i think it's C++), but basically want you should be doing is a for loop to iterate through every character in the string. In Python it would look like:
x = open("text.txt", "r")
y = open("new text.txt","w")
z = ""
for char in x:
z += char.upper()
y.write(z)
I hope I was able to give an idea of how to solve your problem. I'm a newbie as well, but in Python.

C language: reading a .txt file

I'm trying to write a program that reads a text file, using C with Visual Studio.
This is my current code (which doesn't work):
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *filePTR;
char fileRow[100];
filePTR = fopen_s(&filePTR, "text.txt", "r");
// Opens the file
if(filePTR){
while(!feof(filePTR)) {
// Reads file row
fgets(fileRow, 100, filePTR);
// Displays file row
printf("%s \n", fileRow);
}
printf("\nEnd of file.");
}
else {
printf("ERROR! Impossible to read the file.");
}
// Closes the file
fclose(filePTR);
return 0;
}
I'm getting the following warning:
'filePTR' may be '0': this condition does not meet the function specification 'fclose'.
What am I doing wrong? I haven't been programming in C since a while ...
The problems begin long before the fclose. This line is incorrect:
filePTR = fopen_s(&filePTR, "text.txt", "r");
It overwites the file pointer already assigned by passing a pointer as the function argument &filePTR.
The function returns an error status, not the file pointer. Please see the man page:
Return Value Zero if successful; an error code on failure.
Also, please see Why is while ( !feof (file) ) always wrong?
I suggest this:
#include <stdio.h>
#include <stdlib.h>
int main(void) { // correct definition
FILE *filePTR;
char fileRow[100];
if(fopen_s(&filePTR, "text.txt", "r") == 0) {
while(fgets(fileRow, sizeof fileRow, filePTR) != NULL) {
printf("%s", fileRow); // the string already contains a newline
}
fclose(filePTR); // only close if it was opened
printf("\nEnd of file.");
}
else {
printf("ERROR! Impossible to read the file.");
}
return 0;
}
Note that I moved the fclose call up. You can't close a file that you did not open.

How do I remove SEGFAULT here?

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".)

Printing out each line of an input file twice?

I am writing code which very simply reads in a file and prints out what was in the file appropriately.
I have always struggled with getting such a program to terminate upon end of file and think I've found the appropriate solution, however each line is printing twice in my output, for a reason beyond me.
Here is my main file:
int main(int argc, char *argv[]) {
// insure 2 arguments given, one for a.out and one for the test file
if (argc != 2) {
// result if request fails
printf("Requires 2 arguments. Be sure to include test file location\n");
return 0;
}
FILE *fp; //open the file
fp = fopen(argv[1], "r");
char option;
int key;
int i = 0;
while (fscanf(fp, "%c %d", &option, &key) != EOF) {
printf("%d\n", key);
}
}
The key is printing twice!
Hopefully this is a simple error I'm just overlooking due to overexposure to the problem.
You probably want:
fscanf(fp, "%c %d\n", &option, &key);
And you also want to check the return value of fscanf to make sure it equals 2.
In the first iteration of your loop, the newline is not being consumed.
In the second iteration, the newline is consumed and put in option, and the %d does not match, and fscanf returns 1. key is unchanged which is why it gets printed again.
In the third iteration, fscanf finally returns EOF.
General rule: Always check return values to ensure they are what you expect. (You also violate this rule by failing to check the return from fopen.) At worst it does nothing; at best, it helps you debug problems like this.
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Requires 1 argument - a file name\n");
return 1;
}
FILE *fp; //open the file
if ((fp = fopen(argv[1], "r")) == 0)
{
fprintf(stderr, "Failed to open file %s\n", argv[1]);
return 1;
}
char option;
int key;
while (fscanf(fp, "%c %d", &option, &key) == 2)
printf("%d\n", key);
return 0;
}
Note the changes in error reporting, and in the file reading process. The code is still probably not quite what you want; you might get the newline after the number after the first line of input stored in option after the first line. Fixing that requires fgets() and sscanf():
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Requires 1 argument - a file name\n");
return 1;
}
FILE *fp; //open the file
if ((fp = fopen(argv[1], "r")) == 0)
{
fprintf(stderr, "Failed to open file %s\n", argv[1]);
return 1;
}
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp) != 0)
{
char option;
int key;
if (fscanf(fp, "%c %d", &option, &key) == 2)
printf("%d\n", key);
else
{
fprintf(stderr, "Format mismatch on %s", buffer);
fclose(fp); // Not 100% necessary here, but tidiness is important
return 1;
}
}
fclose(fp); // Not 100% necessary here, but tidiness is important.
return 0;
}
Although I closed fp before the end, it is not crucial when the program is about to exit, and return from main() is pretty much equivalent to exit(). If it was in a function other than main() though, it is very important to ensure that you free any resource you allocate, such as the file stream fp.
Warning: uncompiled code. Caveat Lector.

How would I get more then one text file accepted?

Right now, I have something like this...
CMD console window:
c:\users\username\Desktop> wrapfile.txt hello.txt
Hello
How would I get something like this?
CMD console window:
c:\users\username\Desktop> wrapfile.txt hello.txt hi.txt
Hello Hi
with this code?
#include <stdio.h>
#include <stdlib.h>
int main(int argc[1], char *argv[1])
{
FILE *fp; // declaring variable
fp = fopen(argv[1], "rb");
if (fp != NULL) // checks the return value from fopen
{
int i;
do
{
i = fgetc(fp); // scans the file
printf("%c",i);
printf(" ");
}
while(i!=-1);
fclose(fp);
}
else
{
printf("Error.\n");
}
}
Well, first of all: in your main declaration, you should use int main(int argc, char* argv[]) instead of what you have right now. Specifying an array size makes no sense when declaring an extern variable (that's what argv and argc are). On the top of that, you are not using the correct types. argc is integer and argv is array of strings (which are arrays of chars). So argv is an array of arrays of chars.
Then, simply use the argc counter to loop through the argv array. argv[0] is the name of the program, and argv[1] to argv[n] will be the arguments you pass to your program while executing it.
Here is a good explanation on how this works: http://www.physics.drexel.edu/courses/Comp_Phys/General/C_basics/#command-line
My 2 cents.
EDIT: Here is a commented version of the working program.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fp;
char c;
if(argc < 3) // Check that you can safely access to argv[0], argv[1] and argv[2].
{ // If not, (i.e. if argc is 1 or 2), print usage on stderr.
fprintf(stderr, "Usage: %s <file> <file>\n", argv[0]);
return 1; // Then exit.
}
fp = fopen(argv[1], "rb"); // Open the first file.
if (fp == NULL) // Check for errors.
{
printf("Error: cannot open file %s\n", argv[1]);
return 1;
}
do // Read it.
{
c = fgetc(fp); // scans the file
if(c != -1)
printf("%c", c);
} while(c != -1);
fclose(fp); // Close it.
fp = fopen(argv[2], "rb"); // Open the second file.
if (fp == NULL) // Check for errors.
{
printf("Error: cannot open file %s\n", argv[2]);
return 1;
}
do // Read it.
{
c = fgetc(fp); // scans the file
if(c != -1)
printf("%c", c);
} while(c!=-1);
fclose(fp); // Close it.
return 0; // You use int main and not void main, so you MUST return a value.
}
I hope it helps.
argv[2] would be the second file name.
Do not forget to check the value of argc to see if enough arguments are valid.
Better: use boost::program_options.
Caution: this code is not unicode-aware on Windows system, which makes it not portable. Refer to utf8everywhere.org about how to make it support all file names on this platform.

Resources