473,396 Members | 1,784 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Strange issue with fscanf and fgets

52
Hey bytes community!

this one is a really strange issue I ran into and I'm hoping you all can shine some light on it for me.

This is written in C, not C++

I'm working on a program that reads in information from a txt file and outputs it sorted into another txt file.

the code to read from the file looks like this

Expand|Select|Wrap|Line Numbers
  1.     fscanf(fin, "%d", &size);
  2.     deptList = (struct dept*)(malloc(size*sizeof(struct dept)));
  3.  
  4.     for (i=0; i<size; i++) {
  5.  
  6.         fgets(line, MAXLEN, fin);
  7.         strtok(line, delims);
  8.         strcpy(deptList[i].name, line);
  9.  
  10.         p = (char*)strtok(NULL, delims);
  11.         deptList[i].numFaculty = atoi(p);
  12.  
  13.         p = (char*)strtok(NULL, delims);
  14.         deptList[i].totalSalary = atoi(p);  
  15.  
  16.         // Not used.
  17.         p = (char*)strtok(NULL, delims);
  18.  
  19.     }
  20.  
first it reads a number on the first line that lets it know how many lines are to follow. then it allocates memory and reads each line and breaks it up.

Here's the problem. When it starts reading the items into the array the first index (0) doesn't get any information and the second index (1) gets the information from the second line in the file (information that should be in the first index(0))

for the life of me I can't figure out why this isn't working, but i have a suspision that the cursor is left on the first line of the file after the fscanf() call and thus the first fgets() is reading the end of that line and not the second... but like i said... i have no idea.

Any help would be appreciated!
May 19 '08 #1
3 2854
gpraghuram
1,275 Expert 1GB
Hey bytes community!

this one is a really strange issue I ran into and I'm hoping you all can shine some light on it for me.

This is written in C, not C++

I'm working on a program that reads in information from a txt file and outputs it sorted into another txt file.

the code to read from the file looks like this

Expand|Select|Wrap|Line Numbers
  1.     fscanf(fin, "%d", &size);
  2.     deptList = (struct dept*)(malloc(size*sizeof(struct dept)));
  3.  
  4.     for (i=0; i<size; i++) {
  5.  
  6.         fgets(line, MAXLEN, fin);
  7.         strtok(line, delims);
  8.         strcpy(deptList[i].name, line);
  9.  
  10.         p = (char*)strtok(NULL, delims);
  11.         deptList[i].numFaculty = atoi(p);
  12.  
  13.         p = (char*)strtok(NULL, delims);
  14.         deptList[i].totalSalary = atoi(p);  
  15.  
  16.         // Not used.
  17.         p = (char*)strtok(NULL, delims);
  18.  
  19.     }
  20.  
first it reads a number on the first line that lets it know how many lines are to follow. then it allocates memory and reads each line and breaks it up.

Here's the problem. When it starts reading the items into the array the first index (0) doesn't get any information and the second index (1) gets the information from the second line in the file (information that should be in the first index(0))

for the life of me I can't figure out why this isn't working, but i have a suspision that the cursor is left on the first line of the file after the fscanf() call and thus the first fgets() is reading the end of that line and not the second... but like i said... i have no idea.

Any help would be appreciated!

Can you post the file which is being read by the code?

Raghuram
May 20 '08 #2
oler1s
671 Expert 512MB
thus the first fgets() is reading the end of that line and not the second...
Good guess. Let me explain what your code actually does, because of how fscanf and fgets work.

fscanf takes input you give it, and tries to format and store it appropriately. Let's say I wanted to enter the number 5. I hit the keys, 5, and then enter. That's two characters: the character for 5, and the character that matches a newline. fscanf works on this input; it processes the '5' as the number 5. But the newline is not a number, so it's left right in the input stream.

Now fgets runs. Fgets stops reading (and storing the input) when it reaches a newline. But wait, what about the newline already in the stream? It's still there, so fgets picks that up...and then stops. Not what you wanted. You really wish that newline would not stay there.

What I really recommend you do, is avoid using the scanf family. You can always manually parse input as a number using atoi or preferrably strtol. So just use fgets/strtol to do the number input.

What's with the char* cast for strtok? Also, I don't recommend you cast malloc. Casting malloc isn't actually necessary. Furthermore, the cast cannot help you, but it may hurt. The recommended form for malloc is
Expand|Select|Wrap|Line Numbers
  1. p = malloc(n * sizeof *p)
May 20 '08 #3
Shisou
52
Good guess. Let me explain what your code actually does, because of how fscanf and fgets work.

fscanf takes input you give it, and tries to format and store it appropriately. Let's say I wanted to enter the number 5. I hit the keys, 5, and then enter. That's two characters: the character for 5, and the character that matches a newline. fscanf works on this input; it processes the '5' as the number 5. But the newline is not a number, so it's left right in the input stream.

Now fgets runs. Fgets stops reading (and storing the input) when it reaches a newline. But wait, what about the newline already in the stream? It's still there, so fgets picks that up...and then stops. Not what you wanted. You really wish that newline would not stay there.

What I really recommend you do, is avoid using the scanf family. You can always manually parse input as a number using atoi or preferrably strtol. So just use fgets/strtol to do the number input.

What's with the char* cast for strtok? Also, I don't recommend you cast malloc. Casting malloc isn't actually necessary. Furthermore, the cast cannot help you, but it may hurt. The recommended form for malloc is
Expand|Select|Wrap|Line Numbers
  1. p = malloc(n * sizeof *p)
YAY! I was close! thank you so much for clearing that up for me I'll test using another fgets after i post this.

Also, the casting done in the program was actually done by my professor so don't look at me :\

Thanks again!

p.s. the professor also had this same problem in his program that he showed to the class XP
May 20 '08 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: Materialised | last post by:
Hi everyone, I have the following program #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp1, *fp2; char s;
3
by: Benedicte | last post by:
Hi, I'm getting some problems when using fscanf to read a file. This is a piece of the program code: main () { /*** Variable declaration ***/ FILE *vpfile; /*** Data file ***/
7
by: Kay | last post by:
1) If i want to read data from a txt file, eg John; 23; a Mary; 16; i How can I read the above data stopping reading b4 each semi-colon and save it in three different variables ? 2) If I...
5
by: learner | last post by:
I have datafiles like this: 0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 1 0 1941 0.00 0.03 0.00 0.03 0.04 0.02 0.00 0.00 0.00 0.00 2 0 1941 0.00 0.00 0.00 0.00 0.52...
9
by: kvnsmnsn | last post by:
Over the course of my career I've transitioned from an Ada programmer (am I dating myself?) to a C programmer to a Java programmer and now back to a C programmer with the job I've currently...
37
by: PeterOut | last post by:
I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2). I am not sure if this is a C, C++ or MS issue but fscanf has been randomly hanging on me. I make the call hundreds, if not thousands, of...
59
by: David Mathog | last post by:
Apologies if this is in the FAQ. I looked, but didn't find it. In a particular program the input read from a file is supposed to be: + 100 200 name1 - 101 201 name2 It is parsed by reading...
5
by: a | last post by:
After reading FAQ comp.lang.c section 12 and googling again, still there is no threads talking about reading a series of numbers. The input files, somehow structured, is exemplified below: ...
42
by: Bill Cunningham | last post by:
I'm doing something wrong and all I know to do is turn to clc. I have a text file containing 2 doubles separated by a tab. ..26 0 Is the text. I want to read the two double and printf them...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.