Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm writing a program which counts how many times each C keyword is contained in an ASCII file selected by the user. So I use scanf to save the name that the user selected as filename and check with fopen if a file with that name exists in the same dir as the C program. The problem lies in the fact that if the filename selected by the user contains spaces fopen gives an error because it can't find such a file. So here's the question, how do I open a file with fopen that contains spaces in the name of it? Here is the code that i used for the program
selectfilename(filein,1) ;
if (fopen(filein,"r") == NULL){
perror("Error ") ;
return (1) ;
}
void selectfilename(char *cp, int num){
if (num == 1) printf("Please select the name of the file to be opened including the extension : ") ;
else printf("Please select the name of the file to save the statistics including the extension : ") ;
scanf("%s",cp++) ;
}
I think your problem is with scanf, not fopen – which handles filenames with spaces just fine.
scanf("%s") only parse until the first space. It's hard to propose a fix without seeing more of the code.
Update:
Since you read from stdin you can try this to read until the line terminator.
char buf[256];
int rv = scanf ("%255[^\n]", buf); // 255 is max chars to read
if (rv == 0 || rv == EOF)
buf[0] = 0;
printf ("[%s]\n", buf);
Update 2: Fixed bugs reported by #chux
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I need help with this code. You see, it is taking inputs likes strings and integers and saves them in two arrays . Those two should be written into a file with the name "Lagerverwaltung.text". However it just prints a 0 and nothing else into the file.
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char artnr[50],menge[50],me[50],neu[50],date[50];
int zahl, calcam, id, sub,amount;
int greatlen = 0;
int result = 0;
char str[50][50][50];
int mengen[10];
int a = 1;
int s = 0;
while(a > 0){
FILE* fp;
fp = fopen("Lagerverwaltung.txt", "w");
printf("Geben sie eine Zahl ein:");
scanf("%d", &zahl);
if(zahl == 1){
printf("Geben sie ein:\nArtikelnr.:");
scanf("%s",&artnr);
strcpy(str[s][0],artnr);
printf("Menge:");
scanf("%d",&mengen[greatlen]);
printf("Mengeneinheit:");
scanf("%s",&me);
strcpy(str[s][1],me);
printf("Datum:");
scanf("%s",&date);
strcpy(str[s][2],date);
}
fputs(str[greatlen][0], fp);
fprintf(fp, "%d", mengen[greatlen]);
fputs(str[greatlen][1], fp);
fputs(str[greatlen][2],fp);
fclose(fp);
s =s+1;
greatlen = greatlen +1;
}
return 0;
}
There should be a line of integers and strings written into a file.
fopen with "w" parameter opens the file and discards existing content. That means that in each loop iteration you discard whatever you have written previously. Since a never goes to 0, the only option to end the program is to abort it, and you'll be doing that while it waits for input, which is after it has already discarded any file content but before it has written new content.
Possible fixes:
open the file with "a" to append to it
open the file before the loop and close it after the loop (while providing a way to exit the loop).
Also, fix the string-scanning lines like
scanf("%s",&artnr);
that should be
scanf("%s", artnr);
and every decent compiler would warn you about it.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
here is the code given to me and a have also a text file where i need to get the Text from and compile the program.
You need to use open a file with fopen() first. But the current user needs to have perms to read/write the file.
We will use r to only read from a file. If the file is not read it will return NULL. You can fscanf() function to get the value of a file. The second parameter represents the type of the variable as in this case it's a string(char), third param is the mem address of the variable itself. Kind of like file version of scanf().
int main()
{
char a[1000];
FILE *myFile;
if ((myFile = fopen("C:\\myUSER\\newprogram.txt","r")) == NULL){
printf("Error! opening file");
exit(1);
}
fscanf(myFile ,"%s", &a);
printf("Value of a=%s", a);
fclose(myFile);
return 0;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Please, some one can explain for me why this program does not work ?
I'm trying to read and write from the file by using r+. The file test.txt exists and the writing is executed correctly. However, the reading does not work.
int main() {
FILE* fichier = NULL;
int age, TAILLE_MAX=10;
char chaine[TAILLE_MAX];
fichier = fopen("test.txt", "r+");
if (fichier != NULL)
{
printf("give your age ? ");
scanf("%d", &age);
fprintf(fichier, "Hello you have %d year old", age);
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
printf("%s", chaine); //does not print
}fclose(fichier);
}
return 0;
}
By does not work I mean it does not display any thing ! Even if the file contains some the sentence you have ... year old. There is no Error. Just the program does not print the content of the file
you are writing and reading to file at the same time,
which is not good practice,
but the reason your code does not work is because of buffering. The fprintf(fichier, "Hello you have %d year old", age); is likely not happening until your fclose(fichier) statement is happening.
I added the two statements to your code, see below.
Also once you do your fprintf your file pointer fichier is not at the end of the file which is the wrong place for the next thing you try to do which is read the age number you just wrote, so you have to move the file pointer fichier back somehow - I just used rewind which will work if test.txt was a newly created file. Otherwise you will need some method of moving the file pointer fichier backwards just enough to read what you just wrote.
int main() {
FILE* fichier = NULL;
int age, TAILLE_MAX=10;
char chaine[TAILLE_MAX];
fichier = fopen("test.txt", "r+");
if (fichier != NULL)
{
printf("give your age ? ");
scanf("%d", &age);
fprintf(fichier, "Hello you have %d year old", age);
fflush( fichier ); /* force write to FILE */
rewind( fichier ); /* rewind FILE pointer to beginning */
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
printf("%s", chaine); //does not print
}
}
fclose(fichier);
return 0;
}
in your original code, the statement
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
fails to read anything and returns NULL, so the printf("%s", chaine); will not happen. This is happening because of output buffering and the fprintf() statement not happening when you think it should.
This output buffering is normal and if you want a printf to happen at that exact moment then you need to use fflush()
read here to learn more: Why does printf not flush after the call unless a newline is in the format string?
The problem is you try to read from the filehandle after you've written to it.
fichier is like a cursor in an editor, and it only ever has one position in the file. When you open the file with r+ fichier is at the beginning of the file. When you print to fichier it overwrites whatever was at the beginning of the file. Then when you try to read, it reads from where the print left off.
For example, if I start test.txt with some text in it, specifically more than will be printed.
$ cat test.txt
First line
Second line
Third line
Then I run the program.
$ ./test
give your age ? 41
rd line
Notice it printed rd line because that's what's left over after it writes Hello you have 41 year old.
$ cat test.txt
Hello you have 41 year oldrd line
I'm not sure what you're trying to accomplish, but you probably need to fseek to move the cursor to the correct position.
As a side note, wrapping the whole program in if (fichier != NULL) is awkward. And you have no error message if the file does not open, it will quietly and mysteriously do nothing. Instead, check for an error, display an informative message, and exit the program.
#include <string.h>
#include <errno.h>
#include <stdlib.h>
char file[] = "test.txt";
FILE *fichier = fopen(file, "r+");
if (fichier == NULL) {
fprintf(stderr, "Could not open '%s' for r+: %s\n", file, strerror(errno));
exit(1);
}
This is known as early exit and makes code much, much simpler. By taking care of errors immediately, the code can follow a happy path without always needing to be nested in a conditional.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a file that contains:
<Ip_Adress> <User_Id> <User_Name>
When a user wants to change his name he specifics a new one. That new name should replace the in the File. I can do it in two ways: by using C code or with a unix command. I don't have any idea about how to do it using unix but I will prefer that solution. I have tried do it by using C but I get a Segmentation error. I will paste the code. (In the function references the ip address of the user that will change his name)
void change_name(char* ip,char* new_name){
FILE *f1,*f2;
//Attending to one answer I have changed the var to array but the error persists
char buffer[30],ip_address[30],user_id[30],user_name[30];
f1 = fopen ( "data.txt", "r" );
f2 = fopen ( "temporal.txt", "w");
if (f1==NULL){
perror ("Error opening the file data.txt");
fclose(f1);
}
if (f2==NULL){
perror ("Error opening the file temporal.txt");
fclose(f2);
}
while (feof(f1)==0)
{
fscanf(f1,"%s %s %s",ip_address,user_id,user_name);
if(strcmp(ip,ip_address)==0){
fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);
}else{
fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);
}
}
fclose (f1);
fclose (f2);
remove(f1);
rename("temporar.txt","data.txt");
}
An example of data.txt would be:
100.100.1.31 af9a67fa8 Guest
200.200.1.31 a43fji462 Guest
so the problem would be change the specific Guest that matchs with the specific ip given
Example: User with 100.100.1.31 ip address wants to change his name to Superman so the data.txt file will resoult:
100.100.1.31 af9a67fa8 Superman
200.200.1.31 a43fji462 Guest
That command would work
sed -i 's/\(100.100.1.31 .\{9\} \)Guest/\1Superman/g' data.txt
The problem now is to pass it to C with execlp or another command like that.
Your segmentation fault comes from your char * that you use in fscanf.
If you malloc them (or declare them as arrays), it would work.
But, I think that the best way to do it is by using sed. Please, refer to other answers for commands that works
EDIT: You could use asprintf() to simply format your sed regex, and use system() or any derivate you want to call it (system() is the better, it allow you to exec shell commands without forking first).
As I told you in response to your comment, your code doesn't segfaults for me. You could just set ip_address to 16 (255.255.255.255 = 16 char) and user_id to 9, for a better memory usage.
EDIT2:
Here is your code that I modified to make it work. I added comments to let you know what and why I did it.
#include <stdlib.h>
#include <stdio.h>
void change_name(char* ip,char* new_name){
FILE *f1,*f2;
//Attending to one answer I have changed the var to array but the error persists
char ip_address[16],user_id[9],user_name[30]; //Better memory managment
f1 = fopen ( "data.txt", "r" );
if (f1==NULL){
perror ("Error opening data.txt file");
exit(EXIT_FAILURE); //If you can't open first file, exit. File isn't openned, so don't close it.
}
f2 = fopen ( "temporal.txt", "w");
if (f2==NULL){
perror ("Error opening temporal.txt file");
fclose(f1); //Close first file, because you openned it
exit(EXIT_FAILURE); //Then exit
}
while (fscanf(f1,"%s %s %s",ip_address,user_id,user_name)==3) //fscanf returns the number of args read. If not 3, there is a problem.
{ // Directly verify of fscanf avoids the last line double read problem
if(strcmp(ip,ip_address)==0){
fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);
}else{
fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);
}
}
remove((const char *)f1);
rename("temporal.txt","data.txt");
fclose(f1); //Close your files at end, so you will avoid problems when manipulating them
fclose(f2);
}
int main() // Simple test main
{
change_name("100.100.1.31", "Superman");
return (0);
}
Unix commandline, using SED:
sed -i 's/\(100.100.1.31 .\{9\} \)Guest/\1Superman/g' data.txt
That is a regular expression that specifies the IP Address any 9 characters for the UserID, and the Username.
Let's break down that expression:
s/ - Substitute Text
\( - Begin capturing the following text into Param #1
100.100.1.31 - The IP Address you want to match
.\{9\} - Any character (9 times) for the UserID
\) - End the capture to Param #1
Guest - Username you want to match
/ - End the "Search" part, Begin the "Replace" part
\1 - Put Param #1 (IP Address + UserID) here
Superman - Put the new username here
/g - Do this Search-Replace *Globally*
It gets replaced by the same IP Address and 9 characters, but with the username Superman instead of Guest.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to open file in 20 loop. Every time the name of the folder changes.Like This variables1,variables2,variables3......variables20 I found the same question in here , but it didnt help me.
Here's what I have tried:
int l=1;
while(l<20){
char filename[10];
sprintf (filename, "variables%d", l);
OR
scanf("%s", filename);
FILE * fp;
if ((fp = fopen (filename,"rb")) == NULL){
printf("Failed to Open File variables%d\n",l);}
........... Reading Data........
fclose (fp);
l++;
}
I can wite Filename succesfully but I got the error: Failed to Open File variables1
[SOLVED] I am just sodding idiot.Thank you for your concern and answers... i just forgot to add ".bin" sprintf (filename, "variables%d.bin", l);
You never increment your counter.
I would also recommend you to use a for loop like this
for(int i = 1; i < 20; i++){
// Your code
}
Your filename buffer is too short - "variables1" requires 10 characters plus a '\0' terminator, so you need at least 11 characters for this buffer, and more when the index is > 9, otherwise you will get a buffer overflow and undefined behaviour. Change:
char filename[10];
to:
char filename[PATH_MAX]; // PATH_MAX is defined in <limits.h>
Also: if, as your title suggests, you want to write to these files, then you need to change:
if ((fp = fopen (filename,"rb")) == NULL){
to:
if ((fp = fopen (filename,"wb")) == NULL){