Calculate average sea level change - c

This the assignment I'm trying to do.
Download the sea level data from http://climate.nasa.gov/vital-signs/sea-level (Links to an external site.). Create a program that does the following:
a. Tell the user that the program uses data from NASA to predict sea level from the years 2020 to 2050.
b. Store the sea level data in an array. You only need to use one data point for each year from 1993 to the present year. Use the last column for each row (the Global Mean Sea Level GMSL with annual and semi-annual signal removed).
c. Find the average annual change in sea level over all the years specified in the data. (Hint - use a loop to store the annual change in an array over the years, and then use a loop to compute the average annual change).
d. Assume a linear increase and compute the predicted sea level rise for the years 2020, 2025, 2030, 2035, 2040, 2045, and 2050. Store these results in their own array. (Hint - just use the average you computed in part c as the annual change for the future years).
e. Display the results for the user and be sure to reference the data set as specified in the data file so the user knows where the data came from.
Sample output:
The predicted Global Mean Sea Level is
2020 64.32
2025 68.98
2030 73.51
2035 78.12
2040 83.43
2045 88.12
2050 93.04
These predictions were made using data provided by XXXXXXXXXX
This is the code so far. However It seems to not use all of the data in the array to find the average change in sea level.
#include <stdio.h>
#include <stdlib.h>
int main()
{
//creates a file object to read data
FILE* infile = fopen("nasa.txt","r");
//checks if file exists
if(infile == NULL)
{
printf("File does not exist.\n");
return -1;
}
//create 2d array to store years and their sea levels
int level[50][2];
//number of elements in array
int n = 0,i;
char word[5];
//read data from file word by word
while(fscanf(infile, "%s", word) != EOF)
{
if(word != ' ' && word != '\n')
{
//convert string to int and store in array
level[n][0] = atoi(word);
//store sea level
fscanf(infile, "%s", word);
level[n][1] = atoi(word);
//increment n
n++;
}
}
//store avg change
float avg=0;
for(i=1;i<n;i++)
{
//add difference of consecutive elements
avg += level[i][1] - level[i-1][1];
}
//calculate mean
avg = (float)avg/n;
int c = 7; //number of predictions
//array to store results
float predictions[][2] = {{2020,0},{2025,0},{2030,0},{2035,0},
{2040,0},{2045,0},{2050,0}};
//predict future sea levels
for(i=0;i<c;i++)
{
//multiply avg change by number of years
predictions[i][1] = level[n-1][1] +
(predictions[i][0] - level[n-1][0])*avg;
}
//print avg change
printf("Average change in sea level year over year is: %f mm\n",avg);
//print predictions
for(i = 0;i<c;i++)
{
printf("Predicted sea level change since 1993 for the year %.0f: %.2f mm\n",
predictions[i][0],predictions[i][1]);
}
printf("These predictions were made using data provided by the National Aeronautics and Space Administration.");
return 0;
}
Sea level change data
1993 4
1994 7
1995 11
1996 14
1997 21
1998 20
1999 19
2000 22
2001 27
2002 31
2003 34
2004 36
2005 40
2006 42
2007 43
2008 47
2009 48
2010 54
2011 53
2012 59
2013 65
2014 68
2015 75
2016 83
2017 85
2018 88
2019 94

However It seems to not use all of the data in the array to find the average change in sea level.
avg = (float)avg/n; is same as avg = (float)(level[n-1][1] - level[0][1])/n.
Only the end-points matter.
The loop that accumulates the differences is canceling out the in-between year's values.
In a mid-year, if you add +100, it makes one year difference +100 more, and the next year difference 100 less. The running sum of the differences is not affect by that +100 in the end.
All the mid-year values could be 0 and one would get the same average.

Related

Shipping calculator not returning correct results

The assignment is to write a shipping calculator using the following information.
Packages above 50 pounds will not be shipped. You need to write a program in C that calculates the shipping charge.
The shipping rates are based on per 500 miles shipped. They are not pro-rated, i.e., 600 miles is the same rate as 900 miles or 1000 miles.
Here are the shipping charges -
Package Weight Rate per 500 miles shipped
Less than or equal to 10 pounds $3.00
More than 10 pounds but less than or equal to 50 pounds $5.00
If the shipping distance is more than 1000 miles, there is an additional charge of $10 per package shipped.
I originally started writing the program using double but wanted to used a trick I had seen on here to always force the program to round up for the shipping charges by adding 499 to distance then dividing by 500.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int Shipping, packageWeight, packageDistance, packagePrice;
printf("Enter the weight of the package: \n");
scanf("%d", &packageWeight);
printf("The weight you have entered is %.2d\n", packageWeight);
if (packageWeight <= 10 )
Shipping = 3.00;
if (packageWeight <= 50 && packageWeight > 10 )
Shipping = 5.00;
if (packageWeight > 50.0) {
puts("Sorry, we only ship packages of 50 pounds or less.");
return 0;
}
printf("How far are you sending the package? \n");
scanf("%d", &packageDistance);
printf("The distance you entered is %.2d\n", packageDistance);
if (packageDistance <= 1000){
packagePrice = (packageDistance + 499 / 500) * Shipping;
printf("The shipping charge is %.2d \n", packagePrice);
system("pause");
}
if (packageDistance > 1000) {
packagePrice = (packageDistance + 499 / 500) * Shipping + 10.00;
printf("The shipping charge is %.2d \n", packagePrice);
system("PAUSE");
}
}
With a weight of 10 and distance of 501 the output should be a shipping charge of 6 but was 1503
Based on a a weight of 20 and a distance of 1001 the program should output a shipping charge of 25 but was 5000
You have mess with integers / doubles, output, expressions, etc.
Let me show you why you get 1503:
if (packageDistance <= 1000){
packagePrice = (packageDistance + 499 / 500) * Shipping;
printf("The shipping charge is %.2d \n", packagePrice);
system("pause");
}
Your packageDistance is 501 then if statement is true and you get inside.
Then you setup package price. First you get packageDistance which is 501. Then you add it with 499/500 which is 0 since 499 < 500 and you attempt to get integer part of division (as per C/C++ standard). The sum of 501 and 0 is 501.
Now, you multiply it with Shipping. The value you set is 3.0, but smart C convert it to integer 3. 501 * 3 is 1503 and you get the result.
Finally, you try to sent output as %.2d. This is nonsense and I am surprised C shows something at all, but I believe it just see d and ignores .2
This is what you have to do:
Understand your business logic (you do)
Be careful with integers and floating point numbers, read C documentation or send questions here if you do not understand something.
Make sure you use brackets when needed: a + b / c is not the same as (a + b) / c
Make sure you do not use integer division if you mean to use "regular" division.
Make sure you use %d for integers and %.2f for floating point numbers when appropriate.

Breaking an if statement inside a for-loop

How to get loop display to end after execution where gallons < 100 and hours < 24. I'm able to get the "The fish died after ... hours" but unsure how to stop the first printf() in the for loop from executing.
I've tried using a break statement indented in the if statement, but that only affects the for loop.
#include <stdio.h>
int main()
{
double add, vol = 500;
int hour;
printf("Please enter additional water added per hour: ");
scanf("%lf", &add);
for (hour = 1; hour <= 24; hour++)
{
vol = (vol * 0.90) + add;
printf("The volume is %.2f gallons after %d hours.\n", vol, hour);
if (hour <= 23 && vol < 100)
printf("The fish died after %d hours.", hour);
else if (hour == 24 && vol >= 100)
printf("Alas, The fish who lived.");
}
return 0;
}
Expected result:
Please enter additional water added per hour: 6
The volume is 456.00 gallons after 1 hours.
The volume is 416.40 gallons after 2 hours.
The volume is 380.76 gallons after 3 hours.
...
The volume is 103.33 gallons after 22 hours.
The volume is 99.00 gallons after 23 hours.
The fish died after 23 hours.
Actual result:
Please enter additional water added per hour: 6
The volume is 456.00 gallons after 1 hours.
The volume is 416.40 gallons after 2 hours.
The volume is 380.76 gallons after 3 hours.
...
The volume is 103.33 gallons after 22 hours.
The volume is 99.00 gallons after 23 hours.
The fish died after 23 hours. The volume is 95.10 gallons after 24 hours.
C is not Python, indentation is not significant syntactically. Compound statements must be enclosed in {..}:
if (hour <= 23 && vol < 100)
{
printf("The fish died after %d hours.", hour);
break ;
}
else if (hour == 24 && vol >= 100)
{
printf("Alas, The fish who lived.");
}
I suggest you always use {..} for conditional or loop blocks, even for single statements. It makes maintenance simpler.
However, break; is arguably a rather inelegant and poorly structured way of exiting a loop (along with continue). A better structured solution is to terminate the loop by the loop constraint alone. In this case this can be done by:
for( hour = 1;
vol > 100 && hour <= 24;
hour++)
There is the overhead of an additional test but in more complex code than this, with perhaps multiple breaks, it can become difficult to maintain, debug and comprehend.
You are still having a bit of problem figuring out your loop control. You are also inviting an Endless Loop if a matching failure occurs during input because you fail to check the return of scanf (probably one of the biggest pitfalls that new C programmers fall into). Try it. Type "one gallon" at your prompt for input and see what happens. Further, after checking the return, you have to handle 3-cases:
scanf can be used, if used correctly. This means you are responsible for checking the return of scanf every time.
(return == EOF) the user canceled input by generating a manual EOF by pressing Ctrl+d (or on windows Ctrl+z, but see CTRL+Z does not generate EOF in Windows 10 (early versions));
(return < expected No. of conversions) a matching or input failure occurred. For a matching failure you must account for every character left in your input buffer. (scan forward in the input buffer reading and discarding characters until a '\n' or EOF is found); and finally
(return == expected No. of conversions) indicating a successful read -- it is then up to you to check whether the input meets any additional criteria (e.g. positive integer, positive floating-point, within a needed range, etc..).
Onto your loop logic. Given your example and your question "Breaking an if statement inside a for-loop", I think I know where you want to go -- and you can get there with one of the simplest, least used and frankly, mandatory, expressions for nested loop control. The good ole goto statement. It still has a place in programming, and while it should not be overly used, there are a few circumstances, such as those above, and in fact you circumstance, where it is fine to use the goto to jump out of a loop and pass control a few lines down. (the limitation is a longjmp -- you don't want to use it to jump out of a function)
For example, if I understand what you are going for in fish-survival, you can clean up your logic and incorporate the scanf validations by putting the pieces together similar to the following:
#include <stdio.h>
int main (void) {
double add, vol = 500;
int hour;
for (;;) { /* loop continually until valid input is received */
int rtn; /* varible for scanf return - EVERY TIME */
/* there is no conversion taking place, fputs will do */
fputs ("Please enter additional water added per hour: ", stdout);
if ((rtn = scanf ("%lf", &add)) == EOF) { /* handle EOF case */
fputs ("(user canceled input)\n", stderr);
return 1;
}
else if (rtn == 0) { /* handle matching failure */
fputs ("error: invalid double input.\n", stderr);
/* empty all characters from stdin before next input */
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
}
else /* handle good input */
break;
}
for (hour = 0; hour < 24; hour++) { /* loop 0 < 24 */
vol = (vol * 0.90) + add; /* adjust output hour + 1 below */
printf ("The volume is %.2f gallons after %d hours.\n", vol, hour+1);
if (vol < 100) { /* don't forget the '\n' */
printf ("The fish died after %d hours.\n", hour + 1);
goto deadfish; /* jump to deadfish label */
}
}
puts ("Alas, The fish who lived."); /* again, no conversion */
deadfish:; /* good ole goto label */
return 0;
}
(note: generally loop in C will run 0 < n and you adjust the output as required above. While this is not mandatory, it is very much by convention, and accommodates arrays being zero-indexed in C, as well as the hours on a clock that run 0 -> 23, not 1 - > 24. The title of the movie "Zero Dark Thirty" is a good analogy (e.g. zero hour thirty minutes or 12:30 am.) You can't get there looping 1 <= 24, so those limits fail to model the concept of time correctly)
Notice above the use of the goto. It is used in conjunction with the vol < 100 check. If vol < 100 tests TRUE, then control is passed to the label associated with the goto statement. (the label being deadfish:; here). This provides several benefits here. Your for loop can simply track time -- the hours the tank is leaking up to 24. Note how the volume falling below 100 causes control to jump over the living fish output which would execute on normal loop exit.
While you may be able to get your desired dead fish output by incorporating the if (vol < 100) /* print dead fish */; break; else if ... it becomes very difficult to get your /* print live fish */ method on normal loop exit that way without checking the loop counter again as part of the else if clause. The goto provides an elegant solution to just that problem by allowing you to pass control over the /* print live fish */ case when the volume falls below the limit, while at the same time preserving the normal loop exit without having to test your loop counter variable a second time within the loop itself.
Example Use/Output
Make sure your program can handle a cat stepping on the keyboard for every user input. You must Validate every time, e.g.
$ ./bin/deadfish
Please enter additional water added per hour: one gallon
error: invalid double input.
Please enter additional water added per hour: 1
The volume is 451.00 gallons after 1 hours.
The volume is 406.90 gallons after 2 hours.
The volume is 367.21 gallons after 3 hours.
The volume is 331.49 gallons after 4 hours.
The volume is 299.34 gallons after 5 hours.
The volume is 270.41 gallons after 6 hours.
The volume is 244.37 gallons after 7 hours.
The volume is 220.93 gallons after 8 hours.
The volume is 199.84 gallons after 9 hours.
The volume is 180.85 gallons after 10 hours.
The volume is 163.77 gallons after 11 hours.
The volume is 148.39 gallons after 12 hours.
The volume is 134.55 gallons after 13 hours.
The volume is 122.10 gallons after 14 hours.
The volume is 110.89 gallons after 15 hours.
The volume is 100.80 gallons after 16 hours.
The volume is 91.72 gallons after 17 hours.
The fish died after 17 hours.
(cat on keyboard test passed...)
The closest dead fish to 100 gallons:
$ ./bin/deadfish
Please enter additional water added per hour: 6.53
The volume is 456.53 gallons after 1 hours.
The volume is 417.41 gallons after 2 hours.
The volume is 382.20 gallons after 3 hours.
The volume is 350.51 gallons after 4 hours.
The volume is 321.99 gallons after 5 hours.
The volume is 296.32 gallons after 6 hours.
The volume is 273.22 gallons after 7 hours.
The volume is 252.42 gallons after 8 hours.
The volume is 233.71 gallons after 9 hours.
The volume is 216.87 gallons after 10 hours.
The volume is 201.71 gallons after 11 hours.
The volume is 188.07 gallons after 12 hours.
The volume is 175.79 gallons after 13 hours.
The volume is 164.75 gallons after 14 hours.
The volume is 154.80 gallons after 15 hours.
The volume is 145.85 gallons after 16 hours.
The volume is 137.80 gallons after 17 hours.
The volume is 130.55 gallons after 18 hours.
The volume is 124.02 gallons after 19 hours.
The volume is 118.15 gallons after 20 hours.
The volume is 112.86 gallons after 21 hours.
The volume is 108.11 gallons after 22 hours.
The volume is 103.83 gallons after 23 hours.
The volume is 99.97 gallons after 24 hours.
The fish died after 24 hours.
(3 - 100th of a gallon dead)
The first live fish:
$ ./bin/deadfish
Please enter additional water added per hour: 6.54
The volume is 456.54 gallons after 1 hours.
The volume is 417.43 gallons after 2 hours.
The volume is 382.22 gallons after 3 hours.
The volume is 350.54 gallons after 4 hours.
The volume is 322.03 gallons after 5 hours.
The volume is 296.36 gallons after 6 hours.
The volume is 273.27 gallons after 7 hours.
The volume is 252.48 gallons after 8 hours.
The volume is 233.77 gallons after 9 hours.
The volume is 216.94 gallons after 10 hours.
The volume is 201.78 gallons after 11 hours.
The volume is 188.14 gallons after 12 hours.
The volume is 175.87 gallons after 13 hours.
The volume is 164.82 gallons after 14 hours.
The volume is 154.88 gallons after 15 hours.
The volume is 145.93 gallons after 16 hours.
The volume is 137.88 gallons after 17 hours.
The volume is 130.63 gallons after 18 hours.
The volume is 124.11 gallons after 19 hours.
The volume is 118.24 gallons after 20 hours.
The volume is 112.95 gallons after 21 hours.
The volume is 108.20 gallons after 22 hours.
The volume is 103.92 gallons after 23 hours.
The volume is 100.07 gallons after 24 hours.
Alas, The fish who lived.
(saved by 7 - 100th of a gallon -- I'll leave it to you to bisect further into the 1000th of a gallon if you need to)
Look things over and let me know if you have further questions. Put the goto into you C toolbox knowing it should not be over-used, but that it has a few uses where it can provide the optimal solution, and in the case of breaking nested loop, is the only tool in your toolbox that can do it.

I am trying to set a value to an array, but I can't seem to figure out why what I did on line 31 is wrong

I have a data file in the format <0:00> - <19321> , <1:00> - <19324>, up to <24:00> - <19648>, so for every hour there is the total power used so far(the total is incremented), I am supposed to calculate the power used, find the average, and the highest usage of power and its index(time), (I don't need help with finding the max power used at its time index). I traced the problem down to line 31, but I don't understand why what I did was wrong. Can someone explain to me why the code in line 31 isn't saving the value of power used into the array? And how I can fix it? Thanks in advance!
float compute_usage(int num, int vals[], int use[], int *hi_idx)
15 {
16 int i;// i is a general counter for all for loops
17 int r1, r2, u, v, pow_dif, temp;//for loop 1
18 int tot;//for loop 2
19 int max_use, init, fina, diff;//for loop 3 //don't have to worry about this for loop, I am good here
20 float avg;//average power used
21
22 for(r1=r2=i=u=v=0;i<num;i++)//for loop 1
23 {
24 r1= vals[v++];//I set values of every hour as reading 1 & 2(later)
25 #ifdef DEBUG
26 printf("pre-debug: use is %d\n", use[u]);
27 #endif
28 if(r1!=0 && r2!=0)
29 {
30 pow_dif = (r1 - r2);//I take the to readings, and calculate the difference, that difference is the power used in the interval between a time period
31 use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
32 }
33 r2=r1;//the first reading becomes the second after the if statement, this way I always have 2 readings to calculate the power used int the interval
34 #ifdef DEBUG
35 printf("for1-debug3: pow_dif is %d\n", pow_dif);
36 printf("for1-debug4: (%d,%d) \n", u, use[u]);
37 #endif
38
39 }
40 for(tot=i=u=0;i<num;i++)//for loop 2
41 {tot = tot + use[u++];}
42
43 avg = tot/(num-1);
44 #ifdef DEBUG
45 printf("for2-debug1: the tot is %d\n", tot);
46 printf("for2-debug2: avg power usage is %f\n", avg);
47 #endif
Just to understand, how did you figure out that the code in line 31 is problematic? Is it the printf statement in line 36?
When you do this:
use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
printf("for1-debug4: (%d,%d) \n", u, use[u]);
The "u" variable in printf statement is incremented in the previous operation (u++), so you are looking past the element you changed.
use[u++] = pow_dif; //I.e. u=0 here, but u=1 after this is executed.
printf("...\n", u=1, use[1]);
What is the "i" for in this loop? Why don't you try "u++" in the for statement instead of "i++" and remove the "u++" in the use assignment expression?

Why is fscanf changing values of structure without explicitly being told to?

I am trying to read a text file into a structure in c, but on the last iteration of my fscanf() loop, it changes both the numbers and text stored in the first and some of the second parts of my structure.
Debugging has revealed that this behaviour is caused by the while fscanf() loop. Although changing the size of the strings input prevented the numbers being changed, the string on the first line PMs.Party[0] still changed from = Labour to r. Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
void PartyPwr( int Runs, int Time[12], char Prty[12][15]);
struct Data
{
char *Name[12][15];
int StrtMnth[12];
int StrtYr[12];
int EndMnth[12];
int EndYr[12];
char Party[12][15]; // if this is 13 20 it runs without numbers changing.
int TimePwr[12];
};
int main(void)
{
int Max=0;
int i=0;
FILE *PriMins;
struct Data PMs;
if ((PriMins=fopen("PM.txt", "r")) == NULL)
{
printf("Error: PM.txt cannot be read.");
system("pause");
return(1);
}
while(fscanf(PriMins, "%s %d %d %d %d %s", &PMs.Name[Max], &PMs.StrtMnth[Max], &PMs.StrtYr[Max], &PMs.EndMnth[Max], &PMs.EndYr[Max], &PMs.Party[Max]) > 0)
{
PMs.TimePwr[Max]=((PMs.EndMnth[Max] +(PMs.EndYr[Max]*12)) - (PMs.StrtMnth[Max] + (PMs.StrtYr[Max]*12)));
printf("%s %d Total term %d\n",PMs.Name[Max], PMs.EndMnth[Max],PMs.TimePwr[Max]);
printf("Max val, %d bug check %d, %d, Party %s\n",Max, PMs.TimePwr[0], PMs.TimePwr[1], PMs.Party[0]);
Max++;
}
//PartyPwr(Max, PMs.TimePwr, PMs.Party);
//printf("%d, %d", PMs.TimePwr[0], PMs.TimePwr[1]);
fclose(PriMins);
system("pause");
return(0);
}
void PartyPwr( int Runs , int Time[12], char Prty[12][15])
int i=0;
int LabPwr=0;
int ConPwr=0;
for (i=0;i<Runs;i++)
{
printf("%s\n", Prty[i]);
if (strcmp(Prty[i],"Labour")==0)
{
LabPwr=(LabPwr+Time[i]);
}
if (strcmp(Prty[i],"Conservative")==0)
{
ConPwr=(ConPwr+Time[i]);
}
if ((strcmp(Prty[i],"Conservative")!=0) && (strcmp(Prty[i],"Labour")!=0))
{
printf("An invalid party was present in the list.");
}
}
printf ("Total Labour time in power: %d\nTotal Conservative time in power: %d\n", LabPwr, ConPwr);
}
This is the text file for the programme.
Attlee 7 1945 10 1951 Labour
Churchill 11 1951 5 1955 Conservative
Eden 6 1955 12 1956 Conservative
Macmillan 1 1957 10 1963 Conservative
Douglas-Home 11 1963 10 1964 Conservative
Wilson 11 1964 5 1970 Labour
Heath 6 1970 2 1974 Conservative
Wilson 3 1974 3 1976 Labour
Callaghan 4 1976 4 1979 Labour
Thatcher 5 1979 11 1990 Conservative
Major 12 1990 4 1997 Conservative
Blair 5 1997 6 2007 Labour
Brown 6 2007 5 2010 Labour
EDIT: I've just discovered if the size of every variable in Data is increased by one, the code runs without any of the issues. I assume this is some kind of overflow?
EDIT 2: Specifically if EndYr is [13] not [12] the problem is eliminated.
The word Conservative is 12 characters, but you must account for the null char '\0' at the end of every C string.
That is why your code works when you use 13 chars array for the Party field.
What you should do
Specify the maximum length of the Party field in the scanf format specifier. For example, if you keep 12 chars array for the party field:
fscanf(PriMins, "%s %d %d %d %d %11s", &PMs.Name[Max], &PMs.StrtMnth[Max], &PMs.StrtYr[Max], &PMs.EndMnth[Max], &PMs.EndYr[Max], &PMs.Party[Max])
You are reading 13 records from the file and have space to store only 12 of them as all you data items are of size 12.If you increase the size by 1 there is enough room for all 13 records
struct Data
{
char Name[13][15];
int StrtMnth[13];
int StrtYr[13];
int EndMnth[13];
int EndYr[13];
char Party[13][15];
int TimePwr[13];
};

How do you read in a number and a string from a file in C? Keeping in mind that some lines in the file only has a number and not a string

I have a file with multiple lines, and on each line there is a number followed by a space and then a string. But some lines in the file do not have a string following the digit. Here is part of the file:
10
17
38 So You Want to Be a Rock 'N' Roll Star
22 Have You Seen Her Face
12 C.T.A. - 102
16 Renaissance Fair
12 Time Between
23 Everybody's Been Burned
18 Thoughts and Words
12 Mind Gardens
13 My Back Pages
21 The Girl with No Name
3 Why
19 It Happens Each Day
16 Don't Make Waves
13 My Back Pages
12 Mind Gardens
11 Lady Friend
18 Old John Robertson
19
13 Ice Cream Man
14 Hang on Sloopy
Here is what i have so far:
#include <stdio.h>
typedef struct
{
int num_tracks;
char tracks[];
}album_store;
int main(int argc, char *argv[])
{
album_store album[10000];
int numb_tracks;
char line;
int i=0;
if (argc <2 )
{
printf("You need at least one argument\n");
}
else
{
FILE *file;
file=fopen(argv[1],"r");
while(fscanf(file,"%d %[^\n]",&numb_tracks,album[i].tracks) != EOF)
{
album[i].num_tracks=numb_tracks;
printf("%d %s\n",album[i].num_tracks,album[i].tracks);
i++;
}
}
}
Now my code reads in the lines, but not the spaces. Or rather it does not know how to detect if a line does not have a string after the digit. The output of my code looks like:
10 17
38 So You Want to Be a Rock 'N' Roll Star
22 Have You Seen Her Face
12 C.T.A. - 102
16 Renaissance Fair
12 Time Between
23 Everybody's Been Burned
18 Thoughts and Words
12 Mind Gardens
13 My Back Pages
21 The Girl with No Name
3 Why
19 It Happens Each Day
16 Don't Make Waves
13 My Back Pages
12 Mind Gardens
11 Lady Friend
18 Old John Robertson
19 13 Ice Cream Man
My question is how do i get the output of my code to match the input from the file? What would i have to change in my code? Any help is greatly appreciated!
You can't (reasonably) use fscanf() unless you know that all your lines are exactly the same correct format. Instead, I would suggest using fgets() to get one line of text at a time, then parse that line (perhaps using sscanf()).
For example,
char buf[1000];
while (fgets(buf, sizeof(buf), file) != NULL) {
sscanf(buf,"%d %[^\n]",&numb_tracks,album[i].tracks);
// etc
}
You'll want to add checking of the return value of sscanf() to the above sample.

Resources