Why does my fscanf seem to not read anything? - c

I'm trying to make a program in C for reading in lines of text from a file, and creating nodes to build a tree. these nodes are structs. To do this, I'm trying to read six lines at a time. whenever my program gets to the fscanf line however, it doesn't seem to read anything, setting my int to EOF and exiting the function. I've tried a great deal of format combinations, removing and adding spaces, \n and the like. I've even tried making a separate fscanf line to attempt to read in a single string, and even that seems to scan nothing. I have no idea why this is happening. here's the relevant code:
member_ptr readAndCreate(FILE * file){
member_node * temp;
temp = calloc(1, sizeof(member_node));
//char temp_char_array[50] = {0,0,0,0,0};
//char *overflow;
int isEnd;
//isEnd = fscanf(file, " %s", temp_char_array);
//isEnd =
isEnd = fscanf(file, " %[^\n] %[^\n] %d %[^\n] %[^\n] %[^\n]",
temp -> family,
temp -> personal,
&temp ->ID,
temp -> email,
temp -> boatClass,
temp -> boatName
);
//temp->ID = (int)strtol(temp_char_array, &overflow, 10);
if (isEnd == EOF){
printf("Something went wrong, please try again \n");
return NULL;
} else {
return temp;
}
}
and this is the main function
int main() {
char pathname[100];
FILE * file;
member_ptr top;
member_ptr temp;
printf("input file path\n");
scanf("%[^\n]", pathname);
file = fopen(pathname, "r");
if (file == NULL){
printf("file cannot be found, closing program...");
exit(1);
}
top = readAndCreate(file);
genTree(top, file);
printOutTree(top);
printf("Hello, World!\n");
return 0;
}

I see a problem with your scan codes. The s designating string input seems to be missing.
Try changing
isEnd = fscanf(file, " %[^\n] %[^\n] %d %[^\n] %[^\n] %[^\n]",
into
isEnd = fscanf(file, " %[^\n]s %[^\n]s %d %[^\n]s %[^\n]s %[^\n]s",
You have the same bug in the main() function.

Related

My fscanf outputs a large negative number

In this program, I am attempting to read a name and their GPA from a file. The first name is Audrey, then a white space, and then 3.6.
The second line is Oakley, then a white space, and 3.5.
int main()
{
FILE * fPtr;
FILE * fPtr2;
char x[10] = { "Oakley " };
double y;
int z;
fPtr = fopen("data.txt", "r");
if (fPtr == NULL) // open failure
puts("File open for read failed");
else
{
while (scanf("%d", &z) != EOF)
{
fscanf(fPtr, "%s", x);
fscanf(fPtr, "%lf", &y);
fprintf(stdout, "Value read = %s\n", x);
fprintf(stdout, "GPA = %lf \n", y);
}
}
fclose(fPtr);
system("pause");
return 0;
}
So, I tried this once before and it worked. In that attempt, "x[10] = Audrey" and this was the first name in the list. It worked, and the fscanf gave me her GPA. The second time, I tried scanning for Oakley and I still get Audrey, but when I remove that line I get a really large negative number.
I used fscanf because it tokenizes around whitespace, so my theory is that if the cursor gets to the proper name then it will read the next number and that will be the GPA? Right? How do I get it to search for Oakley?
You need check scanf for any errors, which could happen because the input file does not match the format you specified. Try these changes:
char user[100];
while (scanf("%s", user) == 1) {
while (fscanf(fPtr, "%s %lf", x, &y) == 2)
{
if (strcmp(user, x) == 0) {
fprintf(stdout, "GPA for %s is %lf \n", user, y);
break;
}
}
rewind(fPtr);
}
Also, fPtr2 is is uninitialized in your code, remove the line fclose(fPtr2).

read a line of integers from written file? C programming

**I'm still fairly new to C and this is a beginner question. I am trying to read a line of integers separated by a whitespace from a file that I have already written to, but it is not working. When I try to print the integers to screen, I get -1. I'm not sure why this is happening:
#include <stdio.h>
int main() {
//create an array of characters
char str1[10];
//ask the user to enter a file name
printf("Enter a file name\n");
//str1 holds the address of the file name user enters
scanf("%s", str1);
FILE *fp;
fp = fopen(str1, "w+");
//write integer values to created file, separated by a space
fprintf(fp, "%d", 2);
fprintf(fp,"%c", ' ');
fprintf(fp, "%d", 4);
fprintf(fp,"%c", ' ');
fprintf(fp, "%d", 5);
fprintf(fp, "%c", ' ');
fprintf(fp, "%d", 7);
fprintf(fp, "%c", ' ');
fprintf(fp,"%d", 9);
int number;
int counter, c=0;
//if nothing is in file, then print error statement
if (fp==NULL){
printf("File cannot be read");
}
c = fscanf(fp, "%d", &number);
while (c !=EOF){
counter++;
c = fscanf(fp, "%d", &number);
printf("%d",c);
}
fclose(fp);
}
How do I properly print the integers to screen? (count is being used later to calculate the average, and I am originally asking the user to enter a file name that will have integers written to a file)
You have a number of problems:
After writing to the file the position is at the end of the file. Need to rewind to start back at the beginning of the file before reading it.
The printf should print number not c.
The printf should be placed before the fscanf in the loop. Otherwise the first number is missed and the last print is for the fscanf that has returned EOF (ie, number not valid for that last case).

Issue with scanning a character from a file

An issue with my code has risen up in the matter of scanning in characters from a file. Here is my code:
int main(int argc, char **argv){
FILE *ifp = fopen("input.txt", "r");
char check, key;
char buffer[MAX_STRING_LENGTH + 1];
char str[MAX_STRING_LENGTH + 1];
node *head = NULL;
fscanf(ifp, "%s", buffer);
head = stringToList(buffer);
while(fscanf(ifp, "%c", &check) != EOF){
switch(check){
case '#':
//fflush(stdin); //this is commented out because fflush
fscanf(ifp, "%c", &key); //did not seem to solve the issue
fscanf(ifp, "%s", str);
printf("%c, %s\n", key, str);
head = replaceChar(head, key, str);
break;
//more cases follow, but they are irrelevant to this question
My issue here is that my program is failing to scan in a character to key when called. When the input for the particular case from the file says, for example,
# r ri
The print statement gives the following:
( ), (r)
There is a blank space in the print statement which should print r, and as far as I can tell the character is instead scanning into the string. Thus the program is dysfunctional. I need to know how to properly scan in this character. Thank you.
fscanf(ifp, " %c", &key); then fscanf(ifp, " %s", str); notice the additional spaces. You are reading a ' ' after reading the '#'. – David C. Rankin
This has answered my question. Pretty strange that C would be messed up by something so simple.

File processing in C; won't take input

I'm starting to learn file processing in C. The point of this specific program is to make a file called "clients.dat" where I store the account number, name, and balance of clients at a bank, lets say. I've worked and refined the code so that its a perfect replica of what the textbook provides as an example, yet for some reason mine loops endlessly after the first "scanf" and reprints question marks unto oblivion, without ever making it to the scanf statement inside the while loop. Would anyone have any suggestions as to why this is happening? My compiler is Netbeans and I'm running it on Linux-Ubuntu.
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
int main() {
unsigned int actNumber;
char actName[30];
long double actBalance;
FILE *fPtr;
if((fPtr = fopen("clients.dat", "w")) == NULL) {
printf("File could not be found.\n");
}
else {
printf("Enter the Account Number, Name, and Balance.\n Hit the EoF to exit.\n");
printf("%s","?");
scanf("%d%29s%lf", &actNumber, actName, &actBalance);
while (!feof(stdin)) {
fprintf(fPtr, "%d, %29s, %.2lf\n", actNumber, actName, actBalance);
printf("%s", "?");
scanf("%d%29s%lf", &actNumber, actName, &actBalance);
}
fclose(fPtr);
}
return;
}
The end of file marker is set on stdin only when you press a special key combination on the console.
You can make your loop work correctly by using the return value of scanf(), like this
while (scanf("%d%29s%lf", &actNumber, actName, &actBalance) == 3)
{
fprintf(fPtr, "%d, %29s, %.2lf\n", actNumber, actName, actBalance);
printf("%s", "?");
}
After the first scanf() a '\n' character is left in the input stream, when you call scanf() again inside the loop, the character is consumed then ignored, and scanf() fails returning a value that is less than 3, the process is repeated over and over causing the infinite loop.
The following solution, however, is better. Using fgets() allows a better handiling of the '\n' character left unread in the stdin,
char line[100];
while (fgets(line, sizeof(line), stdin) != NULL)
{
if (sscanf(line, "%d%29s%lf", &actNumber, actName, &actBalance) != 3)
continue;
fprintf(fPtr, "%d;%29s;%.2lf\n", actNumber, actName, actBalance);
fprintf(stdout, "?");
}
note that I remove the white spaces in the printf() format, and replaced the , with ; because in some locales the , is the decimal separator, it's just instintictive not to use it, you can use it if you ensure that . is the decimal separator.

Read int and char from the same file in C

I have a text file that looks like this:
i 3755
i 3633
i 4435
i 1434
how would I go about reading this as an input, I've tried using fscanf, but it keeps on giving me a random character after the 'i'
for example output would look like
i% 3755
i5 3633
etc.
Here is what I've been trying:
int data = 0;
char command;
if(fptr==NULL)
printf("File Cannot Be Read");
fscanf(fptr,"%c %d\n", &command, &data);
printf("%c " , command);
printf("%d\n" , data);
fscanf(fptr,"%s %d\n", &command, &data);
printf("%c " , command);
printf("%d\n" , data);
fscanf(fptr,"%s %d\n", &command, &data);
printf("%s " , command);
printf("%d\n" , data);
none of them seem to work. Thanks for your help in advance!
edit: Heres the working code for anybody that was having the same problem:
int data = 0;
char command;
fptr = fopen(argv[1], "r");
if(fptr==NULL)
printf("File Cannot Be Read");
while(fscanf(fptr,"%c %d \n", &command, &data) == 2)
{
if(command == 'i')
{
printf("insert found\n");
}
if(command == 'd')
{
printf("delete found\n");
}
}
}
fscanf(fptr,"%c %d", command, &data);
should be:
fscanf(fptr,"%c %d", &command, &data);
getchar(); // consume the newline character that fscanf left.
Assuming you defined:
char command;
int data;
For simplicity, I would recommend you to, in a loop, read a line using fgets() and then use strtok() to get different 'strings' and then cast according to your parsing methodology. But Mike is right as well, you can use fscanf(fptr, "%c %d\n", &command, &data) to read. When you're using a string, you can ignore the usage of "&" before the variable name. But when its a character or an integer or a float.. you will need to use the address of operator("&")
at this line :
fscanf(fptr,"%c %d", command, &data);
you should give it a pointer to command. like this :
fscanf(fptr,"%c %d", &command, &data);
the next line can't work because the reading cursor is already at the end of the file.
This is incorrect and will result in a buffer overrun:
fscanf(fptr,"%s %d", &command, &data);
as command has only enough space for a single char but fscanf() with format specifier "%s" will read until next whitespace and then write a terminating null character into command. Use a char[] to read and restrict the number of chars to be read.
Note that the NULL check just prints an error message, it does not actually prevent use of a NULL file pointer.
To ensure that each line is of the correct format use fgets() to read a line and then use sscanf() to read the fields. If fscanf() is used to read directly from the file then these two lines:
i
3755
are treated identically to the single line:
i 3755
as a new-line character is also whitespace.
Example:
if (fptr)
{
char line[1024];
while (fgets(line, 1024, fptr))
{
char command;
int data;
if (2 == sscanf(line, "%c %d", &command, &data))
{
/* Use 'command' and 'data'. */
}
}
}
in your fscanf function you have to expect the return to line by adding space at the end of format. Like this
fscanf(fptr,"%c %d ", &command, &data);
The space character replaces return to new line, tabulation and spaces
BTW I see that you use %s to read a char &command and this is incorrect
fscanf(fptr,"%s %d\n", &command, &data);
you have to use this instead
fscanf(fptr,"%c %d ", &command, &data);

Resources