Question

The purpose of this program is to run through user specified data, all data is formatted as hw-data-3.txt where 3 can vary from 1 to 100. I need to iterate through the specified files and add up the total $ spent. There are a maximum of 50 char per line including the \n as well as 30 max lines per file. I'm getting a segmentation fault, I'm pretty sure it's a pointer problem but I'm unsure of where it is. Could anyone help me find it?

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
    char buff[255];int spent[30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},i,z,intbuff[]={0,0,0,0};
    for(i=*argv[argc-2];i>=*argv[(argc-1)];i++)
    {
            sprintf(buff,"hw-data-%d.txt",i);
            FILE *fp;fp=fopen(buff,"r");    /*Initializing and setting file pointer for unknown amount of files*/
            buff[0]='\0';
            while(!feof(fp))    /*while the end of file has not been reached for the stream continue doing these actions*/
            {
                fgets(&buff[0],50,fp); /*captures 1 line at a time from stream then advances the streams position*/
                for(z=0;buff[z]!='\0';z++){
                    if(buff[z]=='$')
                        break;  /*breaks loop at position in line where $ occurs*/}
                for (i=0;i<2;i++,z++){
                    if (buff[z]=='0'||buff[z]=='1'||buff[z]=='2'||buff[z]=='3'||buff[z]=='4'||buff[z]=='5'||buff[z]=='6'||buff[z]=='7'||buff[z]=='8'||buff[z]=='9')
                        intbuff[i]=buff[z];
                    else
                        break;}/* break statement is here to preserve number of integers after $, ie. $100 i=3 $33 i=2 $9 i=1 */
                for (;i>=0;--i)
                {
                    intbuff[3]+=buff[i];
                }               
                for(i=0;i<30;i++)
                {(spent[i]==0)?(spent[i]=intbuff[3]):(0);}/* If i in int array is 0 then replace 0 with the number captured.*/
            }
            fclose(fp);
    }
    return(0);
}
Was it helpful?

Solution

This line is the issue:

for(i=*argv[argc-2];i>=*argv[(argc-1)];i++)

argv[?] is not an int. You have to convert the string to int using one of strtol() family functions.

You code has many other problems:

1) Check the user provides enough arguments (as you are using argv[]).

2) Check the return value of fopen().

3) while(!feof(fp)) is not likely what you want. feof() tells whether you have read past the end of file. Read: Why is “while ( !feof (file) )” always wrong?.

4) The buffer intbuff[] can hold only four ints whereas you seem to store as many ints as provided by the user arguments.

OTHER TIPS

argv[argc-2] is a c-string (type of char*). After dereferencing it you get the first character. You then cast the ASCII value into an int - that won't give you the actual value of that char (let alone the entire numerical value of that argument) - instead use atoi on the arguments to get real integers.

Doing while (!feof(fp)) is a bad practice.
You are assuming fgets() is succeeding.

Try something like this:

while (fgets(&buff[0],50,fp) != NULL)

This line doesn't make much sense either:

for(i=*argv[argc-2];i>=*argv[(argc-1)];i++)

I would try setting up your code somewhat like this:

#include <stdio.h>
#include <stdlib.h>

#define LINE_LENGTH 50
#define MAX_LINES 30

int main (int argc, char *argv [])
{
    int i ;

    char buffer [LINE_LENGTH] = {0} ;

    // Assuming argv[0] is the program name.
    for (i = 1; i < argc; ++i) {
        FILE *fp ;
        fp = fopen (argv [i], "r") ;

        if (fp == NULL) {
            // Handle error...
        }

        while (fgets (buffer, LINE_LENGTH, fp) != NULL) {
            // ...
        }
    }

    return 0 ;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top