sscanf statement stops the program - c

#include <stdio.h>
#include <stdlib.h>
struct urunler {
int kod;
char Ad[16];
int stok;
float fiyat;
};
void urunTara(struct urunler* inputs,int *amount);
int main()
{
struct urunler Urun[50];
int amount = 0;
urunTara(Urun,&amount);
}
void urunTara(struct urunler *inputs,int *amount){
char Temp[150];
FILE *fPtr;
fPtr = fopen("urunler.txt","r");
if(fPtr == NULL){
printf("File not found!");
} else {
while(!feof(fPtr)){
fgets(Temp,100,fPtr);
sscanf(Temp,"%d %s %d %f",&(inputs[*amount].kod),inputs[*amount].Ad,&(inputs[*amount].stok),&(inputs[*amount].fiyat));
*amount++;
}
}
};
I am relatively new to C, and just started learning about structs. The text file contains these:
25 televizyon 1000 150.25
40 video 500 25.45
50 plazma 75 2300.50
76 dvd 20000 90.00
85 supurge 700 110.75
90 buzluk 250 10.00
95 teyp 1250 8.99
The problem i have here is with the sscanf. When i do all these inside the main function, it works great. However when i try to do it in the function urunTara something goes wrong with the sscanf statement and the program stops working. I successfully passed values to &(inputs[*amount].kod) and other adresses by using scanf. But can't understand what's the problem with this sscanf statement.

*amount++;
is similar to
*(amount++);
which means dereference amount and then increment amount to the element after that. Which is not correct.
Change *amount++; to (*amount)++;, which will increment the dereferenced value.
Refer this and this for more details

Related

fscanf returning suspicious data in C

Here is the website of the data files: Group Data Release
And here I am using the catalogs of SDSS_MTV (the third section from the bottom of the webpage).
The data are split into 8 parts. I am trying to read one of these files (such as "Fillingfactor_sdssMth12_80Mpc").
Actually, I am using fscanf() to get the data of "Fillingfactor_sdssMth12_80Mpc". Some of them show the values far greater than 1, that's unreasonable because the filing factor cannot exceed 1.
Here is the excerpt of this file (the first 5 rows):
609d 6c34 417e edb0 2664 0231 4452 3931
d948 2bb2 d877 15b2 0f5b e4b1 b646 9631
470e e3b1 06e2 3fb2 3483 f4b1 2c3d 11b2
6d86 89b1 8135 04b2 005c 44b2 d9eb a4b0
ad80 04b2 8dfb fcb1 03b0 3d32 afc6 4432
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int i;
int Nx,Ny,Nz,itemp;
FILE *fp;
char filename[256];
sprintf(filename,"Fillingfactor_sdssMth12_80Mpc");
Nx=494;
Ny=892;
Nz=499;
float *quan = (float *)malloc(Nx*Ny*Nz*sizeof(float));
fp = fopen(filename,"r");
fread(&itemp,1,sizeof(float),fp);
// Checks the length of the table.
printf("itemp = %i\n", itemp);
if(itemp/sizeof(float) != Nx*Ny*Nz)
{
printf("error! itemp=%d\n",itemp);
exit(1);
}
for(i=0;i<Nx*Ny*Nz;i++)
{
fscanf(fp,"%f",&quan[i]);
printf("grid %i is: %.4lf\n", i, quan[i]);
}
fclose(fp);
}
Could someone explain me what is wrong?

How do you open a FILE with the user input and put it into a string in C

So I have to write a program that prompts the user to enter the name of a file, using a pointer to an array created in main, and then open it. On a separate function I have to take a user defined string to a file opened in main and return the number of lines in the file based on how many strings it reads in a loop and returns that value to the caller.
So for my first function this is what I have.
void getFileName(char* array1[MAX_WIDTH])
{
FILE* data;
char userIn[MAX_WIDTH];
printf("Enter filename: ");
fgets(userIn, MAX_WIDTH, stdin);
userIn[strlen(userIn) - 1] = 0;
data = fopen(userIn, "r");
fclose(data);
return;
}
For my second function I have this.
int getLineCount(FILE* data, int max)
{
int i = 0;
char *array1[MAX_WIDTH];
if(data != NULL)
{
while(fgets(*array1, MAX_WIDTH, data) != NULL)
{
i+=1;
}
}
printf("%d", i);
return i;
}
And in my main I have this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_WIDTH 144
void getFileName(char* array1[MAX_WIDTH]);
int getLineCount(FILE* data, int max);
int main(void)
{
char *array1[MAX_WIDTH];
FILE* data = fopen(*array1, "r");
int max;
getFileName(array1);
getLineCount(data, max);
return 0;
}
My text file is this.
larry snedden 123 mocking bird lane
sponge bob 321 bikini bottom beach
mary fleece 978 pasture road
hairy whodunit 456 get out of here now lane
My issue is that everytime I run this I keep getting a 0 in return and I don't think that's what I'm supposed to be getting back. Also, in my second function I have no idea why I need int max in there but my teacher send I needed it, so if anyone can explain that, that'd be great. I really don't know what I'm doing wrong. I'll appreciate any help I can get.
There were a number of issues with the posted code. I've fixed the problems with the code and left some comments describing what I did. I do think that this code could benefit by some restructuring and renaming (e.g. array1 doesn't tell you what the purpose of the variable is). The getLineCount() function is broken for lines that exceed MAX_WIDTH and ought to be rewritten to count actual lines, not just calls to fgets.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_WIDTH 144
/**
* Gets a handle to the FILE to be processed.
* - Renamed to indicate what the function does
* - removed unnecessary parameter, and added return of FILE*
* - removed the fclose() call
* - added rudimentary error handling.
**/
FILE *getFile()
{
char userIn[MAX_WIDTH+1];
printf("Enter filename: ");
fgets(userIn, MAX_WIDTH, stdin);
userIn[strlen(userIn) - 1] = 0; // chop off newline.
FILE *data = fopen(userIn, "r");
if (data == NULL) {
perror(userIn);
}
return data;
}
/**
* - removed the unnecessary 'max' parameter
* - removed null check of FILE *, since this is now checked elsewhere.
* - adjusted size of array1 for safety.
**/
int getLineCount(FILE* data)
{
int i = 0;
char array1[MAX_WIDTH+1];
while(fgets(array1, MAX_WIDTH, data) != NULL)
{
i+=1;
}
return i;
}
/**
* - removed unnecessary array1 variable
* - removed fopen of uninitialized char array.
* - added some rudimentary error handling.
*/
int main(void)
{
FILE *data = getFile();
if (data != NULL) {
int lc = getLineCount(data);
fclose(data);
printf("%d\n", lc);
return 0;
}
return 1;
}
There are several things I think you should repair at first:
getFileName should help you getting the file name (as the name says), so in that function you shouldn’t have both array1 and userIn (as a matter of fact array1 is not even used in the function, so it can be eliminated all togheter). The paramater and the file name should be ‘the same’.
data is a local FILE pointer, this means once you exit the function you lose it. My recommandation is to make it global, or pass it as an argument from the main class. Also do not close it 1 line after you open it.
I guess the getLineCount is fine, but usually is a good practice to return and printf in main what is returned.
That max that is passed to the second function maybe to help you with the max size of a line? it might be.
Summing up, your getFileName should return the file name, so that userIn is what should be given by that parameter. The File opening should be done IN THE MAIN FUNCTION and be closed after everything you do related to the file, so at the end. Also, open the file after you get the name of the file.
Hopefully it helps you! Keep us tuned with your progress.

Unexpected Output - Storing into 2D array in c

I am reading data from a number of files, each containing a list of words. I am trying to display the number of words in each file, but I am running into issues. For example, when I run my code, I receive the output as shown below.
Almost every amount is correctly displayed with the exception of two files, each containing word counts in the thousands. Every other file only has three digits worth of words, and they seem just fine.
I can only guess what this problem could be (not enough space allocated somewhere?) and I do not know how to solve it. I apologize if this is all poorly worded. My brain is fried and I am struggling. Any help would be appreciated.
I've tried to keep my example code as brief as possible. I've cut out a lot of error checking and other tasks related to the full program. I've also added comments where I can. Thanks.
StopWords.c
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <stddef.h>
#include <string.h>
typedef struct
{
char stopwords[2000][60];
int wordcount;
} LangData;
typedef struct
{
int languageCount;
LangData languages[];
} AllData;
main(int argc, char **argv)
{
//Initialize data structures and open path directory
int langCount = 0;
DIR *d;
struct dirent *ep;
d = opendir(argv[1]);
//Count the number of language files in the directory
while(readdir(d))
langCount++;
//Account for "." and ".." in directory
//langCount = langCount - 2 THIS MAKES SENSE RIGHT?
langCount = langCount + 1; //The program crashes if I don't do this, which doesn't make sense to me.
//Allocate space in AllData for languageCount
AllData *data = malloc(sizeof(AllData) + sizeof(LangData)*langCount); //Unsure? Seems to work.
//Reset the directory in preparation for reading data
rewinddir(d);
//Copy all words into respective arrays.
char word[60];
int i = 0;
int k = 0;
int j = 0;
while((ep = readdir(d)) != NULL) //Probably could've used for loops to make this cleaner. Oh well.
{
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
{
//Filtering "." and ".."
}
else
{
FILE *entry;
//Get string for path (i should make this a function)
char fullpath[100];
strcpy(fullpath, path);
strcat(fullpath, "\\");
strcat(fullpath, ep->d_name);
entry = fopen(fullpath, "r");
//Read all words from file
while(fgets(word, 60, entry) != NULL)
{
j = 0;
//Store each word one character at a time (better way?)
while(word[j] != '\0') //Check for end of word
{
data->languages[i].stopwords[k][j] = word[j];
j++; //Move onto next character
}
k++; //Move onto next word
data->languages[i].wordcount++;
}
//Display number of words in file
printf("%d\n", data->languages[i].wordcount);
i++; Increment index in preparation for next language file.
fclose(entry);
}
}
}
Output
256 //czech.txt: Correct
101 //danish.txt: Correct
101 //dutch.txt: Correct
547 //english.txt: Correct
1835363006 //finnish.txt: Should be 1337. Of course it's 1337.
436 //french.txt: Correct
576 //german.txt: Correct
737 //hungarian.txt: Correct
683853 //icelandic.txt: Should be 1000.
399 //italian.txt: Correct
172 //norwegian.txt: Correct
269 //polish.txt: Correct
437 //portugese.txt: Correct
282 //romanian.txt: Correct
472 //spanish.txt: Correct
386 //swedish.txt: Correct
209 //turkish.txt: Correct
Do the files have more than 2000 words? You have only allocated space for 2000 words so once your program tries to copy over word 2001 it will be doing it outside of the memory allocated for that array, possibly into the space allocated for "wordcount".
Also I want to point out that fgets returns a string to the end of the line or at most n characters (60 in your case), whichever comes first. This will work find if there is only one word per line in the files you are reading from, otherwise will have to locate spaces within the string and count words from there.
If you are simply trying to get a word count, then there is no need to store all the words in an array in the first place. Assuming one word per line, the following should work just as well:
char word[60];
while(fgets(word, 60, entry) != NULL)
{
data->languages[i].wordcount++;
}
fgets reference- http://www.cplusplus.com/reference/cstdio/
Update
I took another look and you might want to try allocating data as follows:
typedef struct
{
char stopwords[2000][60];
int wordcount;
} LangData;
typedef struct
{
int languageCount;
LangData *languages;
} AllData;
AllData *data = malloc(sizeof(AllData));
data->languages = malloc(sizeof(LangData)*langCount);
This way memory is being specifically allocated for the languages array.
I agree that langCount = langCount - 2 makes sense. What error are you getting?

reading a document and finding a specific word in that document

I have the following document:
WTPZ24 KNHC 032040
TCMEP4
TROPICAL STORM SIMON FORECAST/ADVISORY NUMBER 9
NWS NATIONAL HURRICANE CENTER MIAMI FL EP192014
2100 UTC FRI OCT 03 2014
THERE ARE NO COASTAL WATCHES OR WARNINGS IN EFFECT.
TROPICAL STORM CENTER LOCATED NEAR 18.8N 110.6W AT 03/2100Z
POSITION ACCURATE WITHIN 20 NM
REPEAT...CENTER LOCATED NEAR 18.8N 110.6W AT 03/2100Z
AT 03/1800Z CENTER WAS LOCATED NEAR 18.6N 110.1W
FORECAST VALID 04/0600Z 19.2N 112.2W
MAX WIND 65 KT...GUSTS 80 KT.
64 KT... 10NE 0SE 0SW 10NW.
50 KT... 30NE 30SE 20SW 20NW.
34 KT... 50NE 50SE 40SW 40NW.
FORECAST VALID 04/1800Z 20.0N 114.3W
MAX WIND 75 KT...GUSTS 90 KT.
64 KT... 20NE 10SE 10SW 20NW.
and I am trying to make a program in C that will read through the file and find the word string FORECASt VALID. Everytime a line has the words FORECAST VALID I want the program to print the line and "===>" before the line. For the rest of the document I just want it to simply print the line.
The final output put by the program should look like this:
REPEAT...CENTER LOCATED NEAR 18.8N 110.6W AT 03/2100Z
AT 03/1800Z CENTER WAS LOCATED NEAR 18.6N 110.1W
===>FORECAST VALID 04/0600Z 19.2N 112.2W
MAX WIND 65 KT...GUSTS 80 KT.
64 KT... 10NE 0SE 0SW 10NW.
50 KT... 30NE 30SE 20SW 20NW.
34 KT... 50NE 50SE 40SW 40NW.
===>FORECAST VALID 04/1800Z 20.0N 114.3W
MAX WIND 75 KT...GUSTS 90 KT.
64 KT... 20NE 10SE 10SW 20NW.
I do have some snippets of code that print the document verbatim without the ===> but I just need help in how to isolate out FORECAST VALID from a line so as to put the ===> in those lines:
FILE *fr; /* declare the file pointer */
main()
{
int n;
char line[800];
char buf[255];
fr = fopen ("wtnt23.knhc.201410141453", "rt"); /* open the file for reading */
while(fgets(line, 800, fr) != NULL)
{
sscanf (line, "%s", buf);
if (buf="FORECAST")
{
printf("===>%s",line);
}
else
{
printf("%s",line);
}
fclose(fr); /* close the file prior to exiting the routine */
} /*of main*/
if (buf="FORECAST") is totally wrong. it is not compare and you can't copy to char array with a =...
You just need to do like this:
while(fgets(line, 800, fr) != NULL)
{
if(0 == strncmp(line, "FORECAST VALID", strlen("FORECAST VALID")) )
{
printf("===>%s",line);
}
else
{
printf("%s",line);
}
}
I would use std::strings and iostreams rather than char arrays and FILE*.
Something a bit like:
int main()
{
std::ifstream ifs("wtnt23.knhc.201410141453");
std::string line;
while(std::getline(ifs, line)) // loop as long as getline() succeeds
{
if(line.find("FORECAST VALID") == 0) // line starts with this?
{
// output ===>
}
// output line + linefeed
}
}

Please anybody check my code to see what's wrong with it

#include <stdio.h>
int getAvg(int a, int b, int c);
int main()
{
int a,b,c;
int i;
int avg[5];
char name[5][10] ;
int korean[5], english[5], maths[5] ;
char message[2][10] = {"Pass","No Pass"};
for ( i = 0; i < 5; i++ )
{
printf("Enter your marks <name,korean,english,maths \n");
scanf("%s%d%d%d",name[i],&korean[i],&english[i],&maths[i]);
}
for (i = 0; i < 5; i++)
{
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);
avg[i] = getAvg(a,b,c);
if (avg[i]>60)
{
printf("==%s",message[0]);
}
else
{
printf("==%s",message[1]);
}
}
int getAvg(int a, int b, int c)
{
int avg;
avg = (a+b+c)/3;
return avg;
}
}
I want to print like this
Enter your marks <name,korean,english,maths>
kim 10 50 60
Enter your marks <name,korean,english,maths>
hanna 50 60 70
Enter your marks <name,korean,english,maths>
lee 80 70 60
Enter your marks <name,korean,english,maths>
lori 70 80 90
Enter your marks <name,korean,english,maths>
kang 60 70 80
name:kim,korean:10,english:50,maths:60,average:40 == no pass
name:hanna,korean:50,english:60,maths:70,average:60 == no pass
name:lee,korean:80,english:70,maths:60,average:70 == pass
name:lori,korean:70,english:80,maths:90,average:80 == pass
name:kang,korean:60,english:70,maths:80,average:70 == pass
I'm really sorry if it turns out to be my mistakes or the question is too elementary.. it's due in 5 hours and i couldn't figure out what's wrong.. it keeps telling me that the getAve function is undefined reference and i see nothing wrong with it.. please anybody kindly help me? :(
Your getAvg is inside main. Move it out (or, equivalently, move one outer brace from end of your code to just above getAvg definition start). There is also something wrong with the calculation of averages, but that's a logical error, not a syntactic one. (Specifically, you're calculating the average of a, b and c - check where you define the value of those variables, and you're printing stuff before you calculate it).
You get "undefined reference to getAvg function" because you did not close main before defining the getAvg function. Just move the last } before the function definition and that error should be gone !
Then,You call the function like this
avg[i] = getAvg(a,b,c);
But a,b and c are uninitialized ! So you need
a=korean[i];
b=english[i];
c=maths[i];
Before it. You also print avg[i] before you calculate it. So, move the printf after the function call to get the desired results.
After fixing your brace positioning, also there is a problem here:
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);
avg[i] = getAvg(a,b,c);
You have to calculate the average before you display it. Also, a, b, c are uninitialized variables. You probably meant:
avg[i] = getAvg( korean[i], english[i], maths[i] );
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",
name[i], korean[i], english[i], maths[i], avg[i]);
first you put getAvg(...) outside of main()
now call getAvg(...) before printing avg[i];
avg[i] = getAvg(korean[i],english[i],maths[i]);
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);

Resources