populating an array from a text file using fgets - c

I have this program for class where we just need to show that we can read, write and populate an array from both a text and binary file. I didnt have many issued with the binary file but the text file is giving big time brain pains.
I believe this little bit of code is to blame. userInputText[MAXSIZE]is a char array (MAXSIZE is defined at 100000) and both textCount and textCounter are initialized to zero when the program is at this point.
textPointer = fopen("textFile.txt", "r");
if (textPointer)
{
while (fgets(userInputText, sizeof(userInputText), textPointer) != NULL)
{
sscanf(userInputText, "%d", &textCount);
userInputText[textCounter] = textCount;
textCounter += 1;
}
}
When the user first runs the program, this part of the program is skipped and the user is asked to create and write to a text file. The user inputs integers and they are written to a text file and stored in userInputText and displayed to the screen at the end of the program. All of that works fine, the text file is appended correctly every time the program runs. I have tried about every combo I can think of in the above piece of code. I have tried using fopen(r+), sizeof(int and MAXSIZE), experimenting with the %d. In my fprintf part later in the program I have "\n" set as a delimeter, but I have also tried removing it. I switched out the fgets for fread. Ive gotten to the point where I'm resembling a baboon throwing poo at the problem.
I don't want people to think I am lazy and looking for an easy answer, mentally handicapped maybe but not lazy.
Any suggestions?
Thanks,
Mike

Try while( !feof(textPointer) )
{ fgets(userInputText,MAXSIZE,textPointer); }
sizeof(userInputText) will only return the size of a char pointer.

Related

strtok segmentation fault, just gives a segmentation fault when the first line of input file is blank

I am using AIX. There are several posts of Segmentation fault with strtok but I could not find any to help me.
I am writing a c program and I want to read a file in the program and then sort this line (I just need the minutes and the seconds at the end of the second line).
here is a snippet from my code:
FILE *timeFile;
int x, timeElapsed;
char line[1000], *temp;
int main()
{
x = 0;
timeFile= fopen("time.txt", "r");
if(timeFile==NULL)
{
printf("\nerror opening file time.txt\n");
printf("\nPlease update system time manually\n");
return 1;//error
}
while( x<10 && fgets(line, sizeof(line), timeFile)!= NULL)
{
if( x==1 )//we need data from the second line
{
temp = strtok(line, " ");
printf("\nline: %s",line);//the Output here is as expected 'line: real'
printf("\ntemp: %s",temp);//the error occurs here at temp
break;
}
x++;
}
}
The file I am trying to read is has this inside:
real 0m1.25s
user 0m0.09s
sys 0m0.02s
The first line is blank (only a return character I think) and 'real 0m1.25s
' is the second line. I want to read only the second line. The error occurs when I try to read the temp variable.
The funny thing is I have used nearly the same code for the same job in another program and it worked. The only difference was that in the input file of the previous project there were no blank lines or tabs. So I am confused please help.
PS: I am using a German keyboard so it capitalizes words on its own, sorry about that.
Please use sscanf() instead. Try to avoid strtok() at all costs unless otherwise absolutely neccessary.
Here is a link to source you might find useful

displaying contents of a file on monitor in C

I'm trying to recreate a program I saw in class.
The teacher made a file with 10 lines, he showed us that the file was indeed created, and then he displayed its contents.
My code doesn't work for some reason, it just prints what looks like a"=" a million times and then exits.
My code:
void main()
{
FILE* f1;
char c;
int i;
f1=fopen("Essay 4.txt","w");
for(i=0;i<10;i++)
fprintf(f1," This essay deserves a 100!\n");
do
{
c=getc(f1);
putchar(c);
}while(c!=EOF);
}
What is the problem? as far as I can see I did exactly what was in the example given.
The flow is as such:
You create a file (reset it to an empty file if it exists). That's what the "w" mode does.
Then you write stuff. Note that the file position is always considered to be at the very end, as writing moves the file position.
Now you try to read from the end. The very first thing you read would be an EOF already. Indeed, when I try your program on my Mac, I just get a single strange character just as one would expect from the fact that you're using a do { } while. I suggest you instead do something like: for (c = getc(f1); c != EOF; c = getc(f1)) { putchar(c) } or similar loop.
But also, your reading should fail anyway because the file mode is "w" (write only) instead of "w+".
So you need to do two things:
Use file mode "w+".
Reset the file position to the beginning of the file after writing to it: fseek(f1, 0, SEEK_SET);.

How can I edit a text file in C in the easy way?

I have the following code in C. I am trying to look for a line starting with a known word, in order to write back that line with new information. The problem I find is that the stream fp is already after the line I want to edit the moment I find it, so I need to go back to that line in order to write it. How could I do it? Thanks.
FILE *fp;
char line[256];
char description[128];
memset(description, 0, sizeof (description));
if (!(fp = (FILE*) fopen("/etc/samba/smb.conf", "r+"))) {
printf("Error opening smb.conf\n");
return -1;
}
while (fgets(line, sizeof line, fp)) {
if (!strncmp(line, "comment =", 9)) {
sscanf(line, "comment = %[^\t\n]", description);
printf("Old comment found: %s\n",description);
fprintf(fp, "comment = %s\n", "New Comment here");
}
}
fclose(fp);
Even if there was a way to "rewind to previous line", your approach would not work in general. It would only work if you're replacing with a line of the exact same length. (You could make it work for inserting lines shorter than the original with whitespace padding, but not if you want to insert more data than was originally there.)
Create a new file, copy everything there (modifying as you see fit), and replace the original once you've successfully completed.
Alternative, read the file in memory (modifying as you need along the way), and overwrite the original.
You can't "insert" something in the middle of a file without something like the above.
Assuming the file isn't tremendously huge, the easiest way is probably to read the entire file into an array of strings, modify whichever of those strings you want, then write them all back out to disk.
Edit: I do feel obliged to point out that unless you need quite a bit beyond what your question suggests, sed might be a better choice than writing your own program from the ground up.

Debug assertion failed . while using fscanf

Hey I've tried a lot of programs in Visual Studio and in most of them when i try taking the input from a stream ( while using fscanf ) it invariably throws a debug assertion failed error ..
and goes on to say:
stream != NULL. Since I have gotten this error a number of times .. I assume there is a flaw in the way I'm using fscanf. I would appreciate it if someone could tell me the usage or .. give me a demo sample code that illustrates the simple usage .. !
I tried looking up the error .. in most places it said I haven't closed the file .. but I have and I'm a little confused .. I appreciate any help .. thanks a lot :)
printf("Enter No of states\n");
Q=5;
// scanf("%d",&Q);
// READING ZERO MATRIX
// reading the matrix from f0.sta
{
FILE *fp;
fp = fopen("c:\\tc\\fuzzy\\f0.sta","r");
for(i=1;i<=Q;i++)
for(j=1;j<=Q;j++)
fscanf(fp,"%f",&a0[i][j]);
fclose(fp);
}
// READING ONE MATRIX
// reading the matrix from f0.sta
FILE *fp;
fp = fopen("c:\\tc\\fuzzy\\f1.sta","r");
for(i=1;i<=Q;i++)
for(j=1;j<=Q;j++)
fscanf(fp,"%f",&a1[i][j]);
fclose(fp);
This is the code bit.
It sounds like fp is NULL. The most likely reason is that one of the files (or both) do not exist, or can't be opened (for example, because some other process is using it).
I would start by adding some error checking after the two fopen() calls: compare the result to NULL and if it is NULL, examine errno.
Your loop counters start at 1 instead of 0, which is odd for C programming. What's likely happening is you're not allocating enough space in the array, i.e. you have
double a[5][5];
when you need
double a[6][6];
so you're stepping on something past the end of the array. Better to have your loop be
for(i=0;i<Q;i++)
for(j=0;j<Q;j++)
so you don't waste the 0 slots in the array.

Opening a file in C through a proccess

I am trying to create a a program that does the following actions:
Open a file and read one line.
Open another file and read another line.
Compare the two lines and print a message.
This is my code:
#include <stdio.h>
#include <string.h>
int findWord(char sizeLineInput2[512]);
int main()
{
FILE*cfPtr2,*cfPtr1;
int i;
char sizeLineInput1[512],sizeLineInput2[512];
cfPtr2=fopen("mike2.txt","r");
// I open the first file
while (fgets(sizeLineInput2, 512, cfPtr2)!=NULL)
// I read from the first 1 file one line
{
if (sizeLineInput2[strlen(sizeLineInput2)-1]=='\n')
sizeLineInput2[strlen(sizeLineInput2)-1]='\0';
printf("%s \n",sizeLineInput2);
i=findWord(sizeLineInput2);
//I call the procedure that compares the two lines
}
getchar();
return 0;
}
int findWord(char sizeLineInput2[512])
{
int x;
char sizeLineInput1[512];
File *cfPtr1;
cfPtr1=fopen("mike1.txt","r");
// here I open the second file
while (fgets(sizeLineInput1, 512,cfPtr1)!=NULL)
{
if (sizeLineInput1[strlen(sizeLineInput1)-1]=='\n')
sizeLineInput1[strlen(sizeLineInput1)-1]='\0';
if (strcmp(sizeLineInput1,sizeLineInput2)==0)
//Here, I compare the two lines
printf("the words %s and %s are equal!\n",sizeLineInput1,sizeLineInput2);
else
printf("the words %s and %s are not equal!\n",sizeLineInput1,sizeLineInput2);
}
fclose(cfPtr1);
return 0;
}
It seems to have some problem with file pointers handling. Could someone check it and tell me what corrections I have to do?
Deconstruction and Reconstruction
The current code structure is, to be polite about it, cock-eyed.
You should open the files in the same function - probably main(). There should be two parallel blocks of code. In fact, ideally, you'd do your opening and error handling in a function so that main() simply contains:
FILE *cfPtr1 = file_open("mike1.txt");
FILE *cfPtr2 = file_open("mike2.txt");
If control returns to main(), the files are open, ready for use.
You then need to read a line from each file - in main() again. If either file does not contain a line, then you can bail out with an appropriate error:
if (fgets(buffer1, sizeof(buffer1), cfPtr1) == 0)
...error: failed to read file1...
if (fgets(buffer2, sizeof(buffer2), cfPtr2) == 0)
...error: failed to read file2...
Then you call you comparison code with the two lines:
findWord(buffer1, buffer2);
You need to carefully segregate the I/O operations from the actual processing of data; if you interleave them as in your first attempt, it makes everything very messy. I/O tends to be messy, simply because you have error conditions to deal with - that's why I shunted the open operation into a separate function (doubly so since you need to do it twice).
You could decide to wrap the fgets() call and error handling up in a function, too:
const char *file1 = "mike1.txt";
const char *file2 = "mike2.txt";
read_line(cfPtr1, file1, buffer1, sizeof(buffer1));
read_line(cfPtr2, file2, buffer2, sizeof(buffer2));
That function can trim the newline off the end of the string and deal with anything else that you want it to do - and report an accurate error, including the file name, if anything goes wrong. Clearly, with the variables 'file1' and 'file2' on hand, you'd use those instead of literal strings in the file_open() calls. Note, too, that making them into variables means it is trivial to take the file names from the command line; you simply set 'file1' and 'file2' to point to the argument list instead of the hard-wired defaults. (I actually wrote: const char file1[] = "mike1.txt"; briefly - but then realized that if you handle the file names via the command line, then you need pointers, not arrays.)
Also, if you open a file, you should close the file too. Granted, if your program exits, the o/s cleans up behind you, but it is a good discipline to get into. One reason is that not every program exits (think of the daemons running services on your computer). Another is that you quite often use a resource (file, in the current discussion) briefly and do not need it again. You should not hold resources in your program for longer than you need them.
Philosophy
Polya, in his 1957 book "How To Solve It", has a dictum:
Try to treat symmetrically what is symmetrical, and do not destroy wantonly any natural symmetry.
That is as valid advice in programming as it is in mathematics. And in their classic 1978 book 'The Elements of Programming Style', Kernighan and Plauger make the telling statements:
[The] subroutine call permits us to summarize the irregularities in the argument list [...]
The subroutine itself summarizes the regularities of the code.
In more modern books such as 'The Pragmatic Programmer' by Hunt & Thomas (1999), the dictum is translated into a snappy TLA:
DRY - Don't Repeat Yourself.
If you find your code doing the 'same' lines of code repeated several times, write a subroutine to do it once and call the subroutine several times.
That is what my suggested rewrite is aiming at.
In both main() and findWord() you should not use strlen(sizeLineInputX) right after reading the file with fgets() - there may be no '\0' in sizeLineInput2 and you will have strlen() read beyond the 512 bytes you have.
Instead of using fgets use fgetc to read char by char and check for a newline character (and for EOF too).
UPD to your UPD: you compare each line of mike2.txt with each line of mike1.txt - i guess that's not what you want. Open both files one outside while loop in main(), use one loop for both files and check for newline and EOF on both of them in that loop.

Resources