This is a basic address book program that a user can add and delete people from and I am trying to eventually take the data saved in the array and store it in a text file.
In the choose function when ichoice == 8 the program is supposed to print the integer itter to the text file list.txt. It will print 0 when the program first opens and I haven't done anything to change it, but when I add names to the address book causing itter to increase the program crashes whenever I go back and try to save to list.txt.
else if (ichoice == 8) {
FILE *outFile = fopen("list.txt", "w");
if (outFile != NULL) {
printf("%d", itter);
fprintf(outFile, "%d", itter);
}
fclose(outFile);
}
There are some issues in the code fragment:
you fclose(outFile) even if the fopen call was unsuccessful.
you do not append a newline after the number, causing further output to be indistinguishable from the conversion of itter.
fopen("list.txt", "w"); will truncate the file if it already exists: this might not be the expected behavior.
Here is a modified snippet:
else if (ichoice == 8) {
FILE *outFile = fopen("list.txt", "w"); // or possibly "a"
if (outFile != NULL) {
printf("%d\n", itter);
fprintf(outFile, "%d\n", itter);
fclose(outFile);
}
}
Related
I am writing a code that reads the characters from a file, and then if one of these characters is 'A' it should be changed to 'Z', after these changes are made it should write it back to the file (not append, but write), but whenever I open the file after running the code or it is empty, corrupted, or the compiler shouts at me (since I tried correcting it by making some changes, here is the code I have so far:
int main(){
char variable1[2000000];
FILE *filePointer1;
FILE *filePointer2;
int counter;
int exact_char_numb;
filePointer1 = fopen("File.txt", "r");
filePointer2 = fopen("File.txt", "w");
fread(variable1,2000000,sizeof(char), filePointer1);
for(counter = 0; counter<= 2000000 ; counter ++){
if(variable1[counter] == 'A'){
variable1[counter] = 'Z';
}
if(variable1[counter] == '+'){
exact_char_numb = counter; // I am using '+' to mark the end of
} // the file (for now)
}
fwrite(variable1,sizeof(char),exact_char_numb,filePointer2);
printf("%s\n", variable1);
printf("%d\n", exact_char_numb);
return 0;
}
In this call:
fwrite(variable1,sizeof(char),exact_char_numb,filePointer2);
the variable exact_char_numb is likely equal to zero, so you don't get any output. You should turn on all warnings and the compiler will complain to you about the variables that can be used without initializing them first.
"but whenever I open the file after running the code or it is empty, corrupted, or the compiler shouts at me..."
You should check whether the opening of the streams to file.txt were successful by checking the returned pointers for a null pointer before doing any operations with the streams:
if (!(filePointer1 = fopen("File.txt", "r")))
{
fputs("Error occurred at opening file to read!", stderr);
exit(1);
}
if (!(filePointer2 = fopen("File.txt", "w")))
{
fputs("Error occurred at opening file to write!\n", stderr);
exit(1);
}
Furthermore, you donĀ“t need to do have two pointers to two different streams. Use r+ mode:
if (!(filePointer = fopen("File.txt", "r+")))
{
fputs("Error occurred at opening file!", stderr);
exit(1);
}
I can't figure out why this fclose() in my c program is causing bad access. It was working fine and then I changed the if condition to only print when the strings do not equal eachother and suddenly it started causing problems. apart from the bad access error, it is also not printing anything to "newfile.txt"
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int main()
{
FILE * cFile;
FILE *outputfile;
FILE *newfile;
cFile = fopen("input.in", "r");
if (cFile == NULL){
printf("bad input file");
}
newfile = fopen("newfile.txt", "w+");
if (newfile == NULL){
printf("bad newfile");
}
char tempstring[15];
char tempstring2[15];
//get each line in the cFile
while (fscanf(cFile, "%15s", tempstring) != EOF) {
outputfile = fopen("outputlotnum.txt", "r"); //open/(or reopen) outputfile to check lines
if (outputfile == NULL){
printf("bad outputfile");
}
//get each line in the outputfile
while(fscanf(outputfile, "%15s", tempstring2) != EOF){
//if the line from cFile doesn't match the line from outputfile,
//then go ahead and print the line to the newfile.txt
if (strcmp(tempstring, tempstring2) != 0){
fprintf(newfile,"%15s \n", tempstring2);
}
//else don't print anything and continue on to the next line
}
fclose(outputfile); //close the outputfile after checking all the lines for a match
}
fclose(newfile); //throws bad access
fclose(cFile);
return 0;
}
Some reasons for library functions seg faulting include passing bad parameters into the function or that you have a memory scribbler. I suspect that in your case you have overflowed one or both temp string arrays on the stack and have corrupted the file handles. It's generally not a safe operation to fscanf/scanf into a buffer unless you can guarantee that the string you read will fit into that buffer.
To confirm this you could print out the file handles immediately after open, and again before close. They should be the same. If they are not then you have accidentally overwritten them.
I'm a student learning C for the first time. I typed in an example the professor gave the class, which is supposed to read in some integers from a file called "input.txt".
Here's the code:
#include <stdio.h>
int main() {
FILE *ifp;
int num = -1, sum = 0;
ifp = fopen("input.txt", "r");
while (num!= 0) {
fscanf(ifp, "%d", &num);
sum +=num;
}
fclose(ifp);
printf("The sum is %d.\n", sum);
return 0;
}
I'm trying to get this program to print out the "sum" like it should, but when I run it, there are no errors yet the only output I get is (11db).
I created a file called "input.txt" and saved it to the desktop, but it's not working.
The file "input.txt" contains:
1
2
3
4
5
I don't know if I'm supposed to somehow, somewhere, define the file path or where/how to do this.
Any help is much appreciated.
Thanks!
My guess would be that the error is because opening the file fails. You should check that fopen returns non-NULL. Opening a file is an operation that often fails. For example:
ifp = fopen("input.txt", "r");
if (ifp == NULL) {
fprintf(stderr, "Couldn't open the file for reading.\n");
}
Unless given a full path name starting with a "/", fopen opens files in the current working directory of the process, and that is probably not the desktop.
Also, when you reach the end of the file, fscanf will return the value EOF. The variable num will not be set to zero. This is a way to read a file of integers:
while (fscanf(ifp, "%d", &num) == 1) {
sum += num;
}
Trying to work with C I/O currently. I have a file that only holds integers and there is only one per line.. not commas, etc.. what is the best way to read them in:
//WHILE NOT EOF
// Read a number
// Add to collection
I am creating 2 files which is working fine.. but ultimately, I want to read them both in, join them into one collection, sort them and then print them out to a new file. There's no need for you to do all that for me, but please help with the above.. here is my effort so far:
void simpleCopyInputToOutput(void);
void getSortSave(void);
int main()
{
//simpleCopyInputToOutput();
getSortSave();
system("PAUSE");
return 0;
}
void getSortSave(void)
{
FILE *fp1;
FILE *fp2;
FILE *fpMerged;
printf("Welcome. You need to input 2 sets of numbers.\n");
printf("Please input the first sequence. Press 0 to stop.\n");
if ((fp1 = fopen("C:\\seq1.txt", "w")) == NULL)
{
printf("Cannot open or create first file!\n");
exit(1);
}
int num;
int i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp1, "%d\n", num);
i++;
}
printf("Please input the second sequence. Press 0 to stop.\n");
if ((fp2 = fopen("C:\\seq2.txt", "w")) == NULL)
{
printf("Cannot open or create second file!\n");
exit(1);
}
num = -1;
i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp2, "%d\n", num);
i++;
}
fclose(fp1);
fclose(fp2);
if ((fp1 = fopen("C:\\seq1.txt", "r")) == NULL)
{
printf("Cannot open first file!\n");
exit(1);
}
//WHILE NOT EOF
// Read a number
// Add to collection
//TODO: merge ints from both files, sort and output to new file
}
I would suggest you use fgets:
char buffer[16];
while (fgets(buffer, sizeof(buffer), fp1))
{
long value = strtol(buffer, NULL, 10);
/* Use the value... */
}
/* fgets failed ro read, check why */
if (!feof(fp1))
printf("Error: %s\n", strerror(errno));
Edit: How to get the number of entries in the file: If you don't keep track of it any other way (like e.g. having the number of items being the first line), the only solution may be to read the file twice. Once to count the number of lines, and once to read the actual numbers. Use fseek or rewind after the counting to "rewind" the read pointer to the beginning of the file.
I would personally put the counting in a separate function, and also the actual reading. This way you don't have to duplicate code if you want to read from multiple files.
Your problem can be divided into three different parts: reading in two files, sorting the data, and writing the output into a file. I am assuming here that the two input files are not already sorted. If they were, the problem would be greatly simplified (google for mergesort if that is the case).
If you want to open a file for reading, you have to use "r" instead of "w" as file open mode flag. In your example code the read/write parts are somehow reversed from what you describe above. Then you should use fscanf to read formatted input from a FILE*. scanf(...) is just short for fscanf(stdin, ...). You can access the files in the following way:
FILE *fin1 = fopen("seq1.txt", "r");
FILE *fin2 = fopen("seq2.txt", "r");
FILE *fout = fopen("out.txt", "w");
if (fin1 && fin2 && fout) {
// Do whatever needs to be done with the files.
}
if (fout)
fclose(fout);
if (fin2)
fclose(fin2);
if (fin1)
fclose(fin1);
Using dynamic memory to store the integers is difficult. You need to use realloc to grow a buffer as you write more and more data into it, and finally use qsort to sort the data. Someone else can hopefully give more insight into that if needed.
FILE *mails;
FILE *tempmails;
mails = fopen("mailer.txt", "r");
tempmails = fopen ("tempmailer.txt" , "a+");
char line[200],templine[200];
char blnklne[]="\n";
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
while(fgets(templine, sizeof line, tempmails) != NULL)
{
if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
{
flag = 1;
}
}
if(flag == 0)
{
fputs(line, tempmails);
}
}
fclose(mails);
fclose(tempmails);
tempmails = fopen ("tempmailer.txt", "r");
remove("mailer.txt");
FILE *newmails;
newmails = fopen("mailer.txt", "a");
while(fgets(templine, sizeof line, tempmails) != NULL)
{
fputs(templine, newmails);
}
fclose(newmails);
fclose(tempmails);
remove("tempmailer.txt");
I have written the above C code for the following purposes:
Have to read each line from mailer.txt and check if a line is blank or repeated and if both conditions are false have to enter it to a temp file tempmailer.txt
Remove the file mailer.txt and then create a new one and copy enter it into the new file one by one and then remove tempmailer.txt.
But on running what actually happens is:
Copies from mailer.txt to tempmailer.txt ALL the lines irrespective of any conditions given(undesired)
Deletes mailer.txt and creates a new mailer.txt(desired)
Copies from tempmailer.txt to the new file as such(desired)
Deletes tempmailer.txt(desired)
Whatever I do, I can't erradicate this problem. The OS is linux. Please help me. Thanks in advance.
Reset tempmails to the beginning of the file before starting each 2nd loop.
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
rewind(tempmails); /* go back to the begining */
while(fgets(templine, sizeof line, tempmails) != NULL)
{
/* ... */
}
}
You need to seek to the beginning of the file before the second while loop.
As it stands, your second while loop will never find any matching lines because it will always be pointed to the end of the file.
The repeat-detection code is very strange, it's reading from both files at the same time. You can't read from a file opened for append. Try mode a+.
This is solvable with a trivial shell script, do you really have to write it in C?
Maybe this part of code is the reason why you got your question 1
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
while(fgets(templine, sizeof line, tempmails) != NULL)
{
if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
{
flag = 1; /* this part may be not correct */
}
}
if(flag == 0)
{
fputs(line, tempmails);
}
}
If the program finds a line that makes if condition true, then the flag is set to 1, but next line maybe not make if condition true, and you program can not set the flag to 0.So you will never put the mismatch lines which are after the the matched line into the tempmails.
Disclaimer: This is not really an answer, but can definitely aid in debugging!
After the following lines, you should check if the pointers are NULL or not:
mails = fopen("mailer.txt", "r");
tempmails = fopen ("tempmailer.txt" , "a+");
if (mails == NULL) printf("Error: could not open file");
if (tempmails == NULL) printf("Error: could not open file");
Now you can at least know if it can open and read the files. To check whether fgets works, and isn't giving you errors, use ferror or feof.
You should add the same NULL checks for every time you call fopen on a FILE handle.