scanf(" %[^\n]", in);
then for example , i input Knock Knock and hit enter
but my code block inside
if (strcmp ("Knock Knock",out)==0)
does not work
please instruct me ,thanks a lot!
char in[80],out[80];
void input(){
printf("Client: ");
scanf("%[^\n]",in);
fp=fopen("test","w");
if (!fp) return ;
fputs(in,fp);
fclose(fp);
}
fp=fopen("test","r");
fgets(out,81,fp);
fclose(fp);
fp=fopen("test","w");
if (strcmp ("Knock Knock",out)==0)
fputs("Server: Who is there?\n",fp);
First off, the layout of the code is very confusing, and as it stands, it would never compile. You have a function input() that you never seem to call, and you leave code outside the function that should be inside another function, or better yet, all of it should be contained inside a main() function so that it can be executed. Here is a cleaned up example for what you're wanting to-do:
#include <stdio.h>
char in[80],out[80];
int main()
{
printf("Client: ");
scanf("%[^\n]",in); //you really should use fgets() here
FILE* fp = fopen("test.txt","w");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fputs(in,fp);
fputs("\n",fp);
fclose(fp);
fp = fopen("test.txt","r");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fgets(out,80,fp);
fclose(fp);
fp = fopen("test.txt","a+");
if (!fp)
{
perror("Failed to open file");
return 1;
}
if (strcmp ("Knock Knock\n",out)==0)
fputs("Server: Who is there?\n",fp);
return 0;
}
Some important notes:
1) fp has a file-type FILE*, since that is the return of fopen(), but you never declare it as such. So this would never compile with that error.
2) Every time you open a file with the w flag, it erases the entire contents of the file. So if you were intending on appending to the file to have a history of what your output from your program was, you need to use the a+ flag when calling fopen()
3) It would be nice to have some type of error print-out if you failed to open the file rather than scratching your head at why "test.txt" is empty after the program takes the input from stdin. Also if you're going to keep re-opening the file, check for a NULL each time since you're going to get unpredictable results from trying to work with a NULL file pointer (most likely a crash).
4) scanf() can result in nasty buffer over-runs from user-input (or malicious user input) ... use fgets() with stdin to a known-length buffer instead.
You should be able to compile this code now and run it. Works for me with gcc 4.4.3 on Ubuntu. After running, your "test.txt" file should look like:
Knock Knock
Server: Who is there?
Related
#include <stdio.h>
#include <stdlib.h>
struct customer {
char fname[20],lname[20];
int acct_num;
float acct_balance;
};
void main ()
{
FILE *outfile;
struct customer input;
// open Accounts file for writing
outfile = fopen ("C:\\Users\\Admin\\Desktop\\read\\per.dat","w");
if (outfile == NULL)
{
fprintf(stderr, "\nError opening accounts.dat\n\n");
exit (1);
}
// instructions to user
printf("Enter \"stop\" for First Name to end program.");
// endlessly read from keyboard and write to file
while (1)
{
// prompt user
printf("\nFirst Name: ");
scanf ("%s", input.fname);
// exit if no name provided
if (strcmp(input.fname, "stop") == 0)
exit(1);
// continue reading from keyboard
printf("Last Name : ");
scanf ("%s", input.lname);
printf("Acct Num : ");
scanf ("%d", &input.acct_num);
printf("Balance : ");
scanf ("%f", &input.acct_balance);
// write entire structure to Accounts file
fwrite (&input, sizeof(struct customer), 1, outfile);
}
FILE *infile;
/*** open the accounts file ***/
infile = fopen ("C:\\Users\\Admin\\Desktop\\read\\per.dat","r");
if (infile == NULL)
{
fprintf(stderr, "\nError opening accounts.dat\n\n");
exit (1);
}
while (fread (&input, sizeof(struct customer), 1, infile))
printf ("Name = %10s %10s Acct Num = %8d Balance = %8.2f\n",
input.fname, input.lname, input.acct_num, input.acct_balance);
}
when I input info into the program, it just writes random characters in file .dat and doesn't show the info I have written. Please help me to find the problem of that.
You have:
if (strcmp(input.fname, "stop") == 0)
exit(1);
This ends your program at that point. I don't think you want that. Rather, break your loop:
if (strcmp(input.fname, "stop") == 0)
break;
Also, be sure to close your file after you're done writing to it and before you open it for reading. Otherwise, it may not exist or output to it may not be flushed:
fclose(outfile);
Finally, note that fwrite() will write the binary data of your struct. This will look like garbage to the human eye, even though fread() should read it correctly. But note that you should open the file as binary both for reading and for writing. Otherwise, some systems (Windows, at least) will do some interpreting of the data.
outfile = fopen ("C:\\Users\\Admin\\Desktop\\read\\per.dat","wb");
infile = fopen ("C:\\Users\\Admin\\Desktop\\read\\per.dat","rb");
With those changes, your code seems to work fine for me.
Be aware that writing and reading binary data in this way can be fraught with peril if you are using different platforms for writing and reading, sending data over a network, or potentially even using different compile options. Byte ordering ("endianness"), data type sizes, and structure padding can all cause you problems. For real-world problems, some kind of portable serialization would be better.
I want to read a name from a file (for example config_file.txt with only one entry like run)
and then create filenames with that, like run0.txt, run1.txt and so on.
But I get something like run..0.txt with two black dots.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHAR 1000
void generate(char const *fileName);
int main(int argc, char** argv) {
generate("config_file.txt");
}
void generate(char const *fileName) {
char id[MAXCHAR];
FILE *fp;
char str[MAXCHAR];
fp = fopen(fileName, "r");
if (fp == NULL) {
printf("Could not open file %s", fileName);
return 1;
}
while (fgets(str, MAXCHAR, fp) != NULL) {
strcpy(id, str);
}
fclose(fp);
FILE *filePtr;
char filename[100];
for(int i = 0;i < 8;i++){
sprintf(filename, "%s%d.txt", id,i);
filePtr = fopen(filename, "w");
}
fclose(filePtr);
}
As I noted in the comments, your code does not zap the newline that fgets() normally preserves as it reads lines before trying to add the extension to it.
The simple and reliable method for zapping the newline is:
str[stcspn(str, "\n")] = '\0';
There are alternatives that might be more efficient (though efficiency is probably a red herring here — creating files takes a lot longer than reading through a short line of characters), but you have to get a variety of conditions right (empty buffer, buffer with no newline, etc).
You also have:
if (fp == NULL) {
printf("Could not open file %s", fileName);
return 1;
}
You should report errors on stderr instead of stdout.
You might consider including the error number and/or error message.
You should finish the message with a newline.
You can't write return 1; in a function returning void — the compiler must complain about that.
C11 §6.8.6.4 The return statement:
¶1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.
Hence, you should consider writing:
if (fp == NULL)
{
fprintf(stderr, "Could not open file %s for reading: %s\n", fileName, strerror(errno));
return;
}
I normally use a set of error reporting functions that I wrote, one of which tells the library the name of the program (err_setarg0(argv[0]); in main()) and the others of which produce error messages as desired. This code is available in my SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c and stderr.h in the src/libsoq sub-directory.
I'd write:
if (fp == NULL)
err_syserr("failed to open file '%s' for reading: ", fileName);
The function doesn't return. If I wanted to return, I'd use err_sysrem() ('remark') and arrange a return. The sys part of the name means that the error number and message are automatically reported too. I prefer these to perror() because perror() doesn't make it easy to get the program name etc into the error message.
There are analogous libraries available on some systems — err(3) on macOS, and also available on Linux (err(3), does roughly the same job.
It's my first exercise about Files and I have to write some code so that if I write a word in the console, it gets printed in the file. The program ends if I input the word "fine" (it's Italian for end). It seems like the file is opened and closed correctly, the program reads the inserted chars, but nonetheless, the file remains blank.
I tried opening the file in various modes, I tried printing how many chars were read, I even tried deleting the file (but it actually does't exit even if I added exit(1).
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main() {
FILE * fp;
char s[64];
if ((fp = fopen("prova.txt", "r+")) == NULL) {
printf("Error.\n");
exit(1);
}
do {
scanf("%s", s);
if (strcmp("fine", s) != 0) {
fprintf(fp, "%s ", s);
}
} while (strcmp("fine", s) != 0);
fclose (fp);
return 0;
}
It should save all the words in a text file, but it remains blank.
Your program looks OK. Most likely, you are checking the wrong file.
An educated guess: you are using some IDE. If this is the case, the file is created, but is created somewhere else. To be sure, print the working directory (man getcwd) somewhere in the beginning of your program, and look for the file there.
you have to use "w" to open a new file with write priviledges
change
if ((fp = fopen("prova.txt", "r+")) == NULL) {
with
if ((fp = fopen("prova.txt", "w+")) == NULL) {
EDIT: Maybe i didn't explained myself, r+ will fail if the file doesn't exist, changing it works for me
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "ff.txt"
int main() {
char x[10],y[10];
FILE *fp;
fp = fopen(FILE_NAME, "r+");
if (fp == NULL) {
printf("couldn't find %s\n ",FILE_NAME);
exit(EXIT_FAILURE);
}
fprintf(fp,"Hello2 World\n");
fflush(fp);
fscanf(fp,"%s %s",x,y);
printf("%s %s",x,y);
fclose(fp);
return 0;
}
Here's a boiled down version of what I am trying to do. This code doesn't print anything in the console. If I remove the fprintf call, it prints the first 2 strings in the file, for me its Hello2 World. Why is this happening? Even after I fflush the fp?
After fprintf(), the file pointer points to the end of the file. You can use fseek() to set the filepointer at the start of the file:
fprintf(fp,"Hello2 World\n");
fflush(fp);
fseek(fp, 0, SEEK_SET);
fscanf(fp,"%s %s",x,y);
Or even better as suggested by #Peter, use rewind():
rewind(fp);
rewind:
The end-of-file and error internal indicators associated to the stream
are cleared after a successful call to this function, and all effects
from previous calls to ungetc on this stream are dropped.
On streams open for update (read+write), a call to rewind allows to
switch between reading and writing.
It is always best to check the return code of fscanf() too.
To avoid buffer overflow, you can use:
fscanf(fp,"%9s %9s",x,y);
I'm testing out the basic functions to operate files with.
I try to first open/close a file to create it, and then open/close it again to append to it. Lastly, I print out what is in the file.
My code currently looks like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * file;
char mark;
/* WRITING: */
file= fopen("goodbye.c","w");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
printf("Enter data to write to .c file:");
while((mark= getchar())!=EOF)
{
putc(mark,file);
}
fclose(file);
/* APPENDING: */
file= fopen("goodbye.c","a");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
char add;
scanf("%c",add);
putc(add,file);
fclose(file);
/* READING: */
file= fopen("goodbye.c","r");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
while((mark= getc(file))!= EOF)
{
printf("%c",mark);
}
fclose(file);
}
With this, I'm not able to append to the file. When using getchar(), I type ctrl+d once finished writing in the first place. After this it goes on to printing out what I just wrote, not giving me the chance to append to the file. Does ctrl+d somehow interrupt with scanf?
And how to get the result that I was looking for?
Your code only allows you to append a single character to the file, which is a little stingy. It can also (at least in theory) lead to problems on some systems if the last line of the text file does not end with a newline, which it won't if you add something other than a newline. Maybe you need a loop to read multiple characters?
Also, since you don't stop the initial input until EOF, you need to clear the 'error' on stdin with clearerr(stdin) to allow further input to occur. This works correctly on Mac OS X 10.10.1 Yosemite; it should work the same on other Unix systems. I can't answer confidently for Windows-based code unless it is using something like Cygwin to simulate Unix, but I expect it would work in much the same way there, too, even with MSVC.
Incidentally, my compiler complains about a missing & in the call to scanf() at:
char add;
scanf("%c",add);
If your compiler doesn't complain, either turn up the warning level or get a better compiler.
This code works as I'd expect:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *file;
char mark;
/* WRITING: */
file = fopen("goodbye.c", "w");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
printf("Enter data to write to .c file:");
while ((mark = getchar()) != EOF)
{
putc(mark, file);
}
fclose(file);
printf("EOF 1\n");
/* APPENDING: */
file = fopen("goodbye.c", "a");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
clearerr(stdin);
char add;
while (scanf("%c", &add) == 1)
putc(add, file);
fclose(file);
printf("EOF 2\n");
/* READING: */
file = fopen("goodbye.c", "r");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
while ((mark = getc(file)) != EOF)
{
printf("%c", mark);
}
fclose(file);
return 0;
}
The only substantive changes are adding a loop around the scanf() — though frankly it would be better to use getchar() again, like in the first input loop — fixing the call to scanf(), adding the two printf() statements that report when EOF is detected, and including clearerr(stdin); to allow input to continue.
Sample output
Code without clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
Code with clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
But it helps when you add the clearerr(stdin) to this one.
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
But it helps when you add the clearerr(stdin) to this one.