954,496 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Having trouble displaying an Arrays. Please help.

I'm fairly new to C and have been doing pretty good up until arrays. I understand the basics of them but not exactly how to use and impliment them in more complicated ways.

I am trying to write a program that will display a table of strings and intigers from an input file that contains both, converting the time to the standard minute:second format in a seperate function.
It should display the first the song number, then the time, then the song name.

Like this:

[ 6] 8:17 Don't Get Fooled Again

This is what I have so far.
vvvv

This is just the array delclarations.

char names[99][28]= {" "};
int time[99]={0};

Here it starts.

void fillTable(char names[], int time[], int count, int seconds)
{
     FILE *inp;
     int *status;
     char list[99];
     inp = fopen("songdata.txt", "r");
     count=0;
    
     while(status != EOF);
     {
          status = fgets(list, 80, inp);
          fscanf(inp, "%d", &seconds);
          list[count] = names[count];
          seconds = time[count];
        printf("[%d]", count);
          ++count;
     }
    fclose(inp);
}

/*Time Calculator*/

void showTime(int time[],int min, int sec, int count)
{   
    int index, seconds;
    for (index=0; index < count; index++)
    {  
         time[count] = seconds;
         min = (seconds/60);
         sec = (seconds%60);
         printf("%2d:%02d", min, sec);
     }
}

/*Table Display*/

void showTable(int time[], char names[], int count, int min, int sec)
{ 
    int index;
     int column[99];
    for (index=0; index < count; index++)
    {   
             printf("%s", &names[index]);
    }
}

/*Main Function Start*/

int main (void)
{   
    int sec, min, count;
     
         showTable(time, *names, count, min, sec);
         showTime(time, min, sec, count);
     
     return(0);
}

Nothing aside from the initial time function is working (don't even know if that for loop is doing what I want it to.:sad:
I know it's a bit long, but help is much appreciated.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

This is all part of a bigger program, but I figure if I can get the arrays to display correctly I can figure out the rest.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Acquire,

The first thing I noticed was this char names[99][28]= {" "}; . If you get an error with that line, try using single quotes instead of double quotes. Double quotes are associated with strings, while single quotes are for char's, which is what you are using. It should look like char names[99][28]= {' '};

Also, in your fillTable procedure, what are you using list[99] for? You declare it inside the function, and assign it values, and then it goes nowhere. Also, names[][] is a two dimensional array, where you declared list[] as one. This may pose problems when you are trying to assign names to list in the function.

Another thing that may be a problem: In main, when you call showtable you pass *names. Arrays are always passed by reference so you do not need the *.

Also, in your declaration of

void showTable(int time[], char names[], int count, int min, int sec)


names should look like char names[][] to match the way you declared names. (it should also be used throughout the program as a two dimenasion array. you should always access names with two parameters. Eg. names[x][y], names[10][3])

I hope these help you out. Keep posting.

nanodano
Junior Poster in Training
78 posts since Feb 2005
Reputation Points: 36
Solved Threads: 2
 

Since I declared the arrays as

char names[99][28]= {"                            "};
int time[99]={0};



does that mean I should put those values as parameters in each of the functions?Also, in your fillTable procedure, what are you using list[99] for? You declare it inside the function, and assign it values, and then it goes nowhere. Also, names[][] is a two dimensional array, where you declared list[] as one. This may pose problems when you are trying to assign names to list in the function.
I'm using the list[][] array to store the strings from the file and then move them into the names array. The reason it's a 2D array is because since it's storing strings, each string is an array as well as each line of strings. I am supposed to store them all into the array, but the length of each string must only be up to 28 characters. If I try to make list a 2D array, it gives me this error:

warning: passing arg 1 of `fgets' from incompatible pointer type

That's why I was thinking of just storing it into a single parameter array, then storing that array into the names array.

Also, in this part:

while(status != EOF);
     {
        <strong>status = fgets(list, 80, inp);</strong>
          fscanf(inp, "%d", &seconds);
          list[count] = names[count];
          seconds = time[count];
        printf("[%d]", count);
          ++count;
     }


I get this error:

warning: assignment makes integer from pointer without a cast

in this line

status = fgets(list, 80, inp);

That part I just don't understand. I've seen examples of the loops using EOF, but mine won't seem to work.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 
I'm using the list[][] array to store the strings from the file and then move them into the names array.

You use list = names which assigns names to list in your code. You may mean to have that switched. Also, why not read directly into names? I am pretty sure your dispute between 1 and 2 dimensional arrays is what is causing the integer/pointer warning

nanodano
Junior Poster in Training
78 posts since Feb 2005
Reputation Points: 36
Solved Threads: 2
 
char names[99][STRSIZ]= {"                            "};
int time[99]={0};

/*Table Contstruction*/

void fillTable(char names[99][STRSIZ], int time[99], int count, int seconds)
{
     FILE *inp;
     int status;
     char list[99];
     inp = fopen("songdata.txt", "r");
     count=0;
     
     while(status != EOF);
     {
        status = fgets(list, 80, inp);
          fscanf(inp, "%d", &seconds);
          strncpy(names[count], list, 28);
          seconds = time[count];
        printf("[%d]", count);
          ++count;
     }
    fclose(inp);
}

/*Time Calculator*/

void showTime(int time[],int min, int sec, int count)
{   
    int index, seconds;
    for (index=0; index < count; index++)
    {  
         time[count] = seconds;
         min = (seconds/60);
         sec = (seconds%60);
         printf("%2d:%02d", min, sec);
     }
}

/*Table Display*/

void showTable(int time[99], char names[99][STRSIZ], int count, int min, int sec)
{ 
    int index;
     int column[99];
    for (index=0; index < count; index++)
    {   
        
             printf("%s", names[index]);
    }

/*Main Function Start*/

int main (void)
{   
    int sec, min, count;
    showTable(time, names, count, min, sec);
    showTime(time, min, sec, count);
         
    printf("Song number?");     
    return(0);
}



the only error I get now is this:
warning: assignment makes integer from pointer without a cast

in this line Code:
status = fgets(list, 80, inp);

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

>> status = fgets(list, 80, inp);

fgets() does not return an integer -- it returns char*. And your loop is incorrect

while(fgets(list, 80, inp) != NULL);
     {
          // blabla
   };


>> fscanf(inp, "%d", &seconds);
fscanf() is the wrong function because it redads from a file not from memory. Since the digits have already been read using fgets(), just use atol() to confert to int

seconds = atol(inp);
Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 
>> fscanf(inp, "%d", &seconds); fscanf() is the wrong function because it redads from a file not from memory. Since the digits have already been read using fgets(), just use atol() to confert to int


But I used gets to to read the strings. The input file contains both intigers and strings. That's what my proffesor said to do, read the strings with gets, then the intigers with a fscanf.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Okay, update. I've got this thing displaying and doing time stuff.

#include <stdio.h>
#include <string.h>
#define MAXTIME 3000
#define STRSIZ 99
#define SENTINEL 0

/*Array Declarations*/

char names[99][STRSIZ]={"                              "};
int time[99]={0};
int select[99]={0};

/*Table Contstruction*/

int fillTable(char names[][STRSIZ], int time[99], int count)
{
     FILE *inp;
     char list[99];
     int index;
     int status;
     int number;
     inp = fopen("songdata.txt", "r");
     index = 1;
     
     for(index=1; index <9; index++)
     /*while(status !=EOF)*/
     {    
         status = fscanf(inp, "%d", &number);  
          time[index] = number;
          fgets(list, 99, inp);  
          strncpy(names[index], list, 28);
          names[index][29] = '\0';          
     }
   fclose(inp);
    count = index;
    return (count); 
}

/*Time Calculator*/

void showTime(int seconds)
{   
    int min, sec;
    min = (seconds/60);
     sec = (seconds%60);
     printf("%2d:%02d", min, sec);
}

/*Remaining Time Function*/

int getRemainingTime(int time [], int seconds, int remaining, int total_time)
{
     remaining = MAXTIME - total_time;
     return (remaining);
}

/*Table Display*/

void showTable(int time[99], char names[][STRSIZ], int select[99], int count, int min, int sec, int seconds, int remaining, int total_time, int songnum)
{ 
    int index;
    for (index=1; index < count; index++)
    {   
         if(select[songnum] == !select[songnum])
          {
            printf("*");
          }
          else
          {
              printf(" ");
          }
          printf(" [%d] ", index);
          seconds = time[index];
         showTime(seconds);          
         printf("%s\n", names[index]);
     }     
     printf("                                            Total: ");showTime(total_time);
     remaining = getRemainingTime(time, seconds, remaining, total_time);
     printf("  Remaining: ");showTime(remaining);
}

/*Main Function Start*/

int main (void)
{   
    int sec, min, count, seconds, remaining, total_time, songnum, index;
     index = 1;
     songnum = 1;
     total_time = 0;
     while(songnum != SENTINEL)
     {
         count = fillTable(names, time, count);
         seconds = time[index];
         total_time = total_time + time[songnum];
         showTable(time, names, select, count, min, sec, seconds, remaining, total_time, songnum);
         getRemainingTime(time, seconds, remaining, total_time);
     
         printf("\nSong number?\n");    
         scanf("%d", &songnum);
         printf("\n");
     } 
     return(0);
}
Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Now, I'm supposed to use a thrid array (select[99]) to display the songs on either side of the table.
---
[ 1] 3:01 Hey Jude [ 4] 9:03 Riders On The Storm
[ 2] 3:00 Stairway to Heaven [ 7] 21:05 Thick As A Brick
[ 3] 3:59 Radar Love
[ 5] 4:05 What's So Funny? ('bout Peac
[ 6] 8:17 Don't Get Fooled Again
[ 8] 18:50 Close To The Edge
Total: 30:08 Remaining: 19:52
Song number?
---
Supposed to look something like that, two columns, one for the list of songs, and the other for the songs that have been chosen. (Except in actual columns, the spaces don't show up here for some reason) The Total time of songs displayed at the bottom and remaining time at the bottom aswell. I was told to first try to get it to display an "*" in front of the songs chosen, that way I got something working.

So that example would then look something like this:

---
[ 1] 3:01 Hey Jude
[ 2] 3:00 Stairway to Heaven
[ 3] 3:59 Radar Love
*[ 4] 9:03 Riders On The Storm
[ 5] 4:05 What's So Funny? ('bout Peac
[ 6] 8:17 Don't Get Fooled Again
*[ 7] 21:05 Thick As A Brick
[ 8] 18:50 Close To The Edge
Total: 30:08 Remaining: 19:52
Song number?
---

I'm supposed to do an if statment for the one that will display an asterik. Something like:

IF (select[]something)
print *
else
print (" ")

My professor during class said something about doing a logical not with the select[] array. Like putting:
if(select[songnum] = !select[songnum]) (???)

(songnum is the variable that stores the number of the song... and select[] is initialized to all zero's because it's supposed to be logical, returning 0 for false and opposite for true, thus deciding where to display the song title)

But I didn't understand... These selected songs should be added to the total time and subtracted from remaining time. My program already does that. But it also must subtract the song from the total (add to remaining) if I call it's number again. That I haven't figured out yet. Any hints on getting the asteriks and time thing to work would be much appreciated.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

This is the whole text file:

181 Hey Jude
180 Stairway to Heaven
239 Radar Love
543 Riders On The Storm
245 What's So Funny? ('bout Peace, Love, and Understanding)
497 Don't Get Fooled Again
1265 Thick As A Brick
1130 Close To The Edge

The way I have it set up, it scans intigers, then does fgets for the string, then does intigers again and so on.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

I'm also having a problems with this section of my function. I am currently using a for loop, when it should be a while loop. The commented while loop there is what I'm trying to do, but it won't work, the program won't display anything.

int fillTable(char names[][STRSIZ], int time[99], int count)
{
     FILE *inp;
     char list[99];
     int index;
     int status;
     int number;
     inp = fopen("songdata.txt", "r");
     index = 1;
     
     for(index=1; index <9; index++)
     /*while(status !=EOF)*/
     {    
         status = fscanf(inp, "%d", &number);  
          time[index] = number;
          fgets(list, 99, inp);  
          strncpy(names[index], list, 28);
          names[index][29] = '\0';          
     }
   fclose(inp);
    count = index;
    return (count); 
}
Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

:sad:

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 
:sad:


:mrgreen:
don't bump posts. When someone that can help comes along, they will. :evil:I'm also having a problems with this section of my function. I am currently using a for loop, when it should be a while loop. The commented while loop there is what I'm trying to do, but it won't work, the program won't display anything.
...

for(index=1; index <9; index++)
     /*while(status !=EOF)*/


These two loops have nothing in common. Change the while loop to look like the for loop.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Okay I figured that part out, don't know how I didn't notice I had to scan the first line outside the loop

int fillTable(char names[][STRSIZ], int time[99], int count)
{
     FILE *inp;
     char list[99];
     int index;
     int status;
     int number;
     inp = fopen("songdata.txt", "r");
     index = 1;
     
         status = fscanf(inp, "%d", &number);
     while(status !=EOF)
     {    
          time[index] = number;
          fgets(list, 99, inp);  
          strncpy(names[index], list, 28);
          names[index][29] = '\0';          
status = fscanf(inp, "%d", &number);  
     }
   fclose(inp);
    count = index;
    return (count); 
}
Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Now, this part is my main problem. I'm trying to make it so that in my main function, when I select the songnumber of a certain song, it displays an "*" in front of the number. I don't understand how though.

void showTable(int time[99], char names[][STRSIZ], int select[99], int count, int min, int sec, int seconds, int remaining, int total_time, int songnum)
{ 
    int index;
    for (index=1; index < count; index++)
    {   
         if(select[songnum] == !select[songnum])
          {
            printf("*");
          }
          else
          {
              printf(" ");
          }
          printf(" [%d] ", index);
          seconds = time[index];
         showTime(seconds);          
         printf("%s\n", names[index]);
     }     
     printf("                                            Total: ");showTime(total_time);
     remaining = getRemainingTime(time, seconds, remaining, total_time);
     printf("  Remaining: ");showTime(remaining);


}
Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 
These two loops have nothing in common. Change the while loop to look like the for loop.

Dont you think you are forgetting something in your code -- something like incrementign the index value so as to provide the terminating condition for the loop.

while(status !=EOF)
     {    
          time[index] = number;
          fgets(list, 99, inp);  
          strncpy(names[index], list, 28);
          names[index][29] = '\0';          
          status = fscanf(inp, "%d", &number);  
          ++ index ;
     }
}


Also If you sure that there are only 8 records then why not:

index = 1 ;

while( index < 9 )
{
  // your stuff goes here
  ++ index ;
}
~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 

:lol: I forgot to put that in the code I posted. But, as of now, my while loop, my whole fillTable function, works. The problem is the show table one, where I need it to either put an "*" if I select the song, or nothing if I don't. Also, I initially had a for loop because the file my professor provided for us does only have 8 lines, but, he said that we have to make it so that it can accept a file up to 99 lines. That's why it has to be like that.

Acquire
Light Poster
30 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Hmm.. if the number of entries in the file can range from 8 to 99.. why bother creating a static array which will unnecessarily take up space. Why not do it in a more effective way:

char buffer[512] = { '\0' } ;

// keep on reading from file till EOF
while( fgets( buffer, 512, file_pointer ) )
{
   sscanf( buffer, ......
   // and so on..
}


This will make your code flexible, be it 99 or 999 lines.

As far as the display part is concerned, when you accept the input from user which is the song number, store it is a variable like "tmp_num".
Run a for loop through the entries of your array and if the "tmp_num" matches with any select[index] then print out an * in front of only "names[index]" .

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 
Now, this part is my main problem. I'm trying to make it so that in my main function, when I select the songnumber of a certain song, it displays an "*" in front of the number. I don't understand how though.


If you think about it, when can if(select[songnum] == !select[songnum])
ever be true? Isn't this the same as if(val == !val) ?

Maybe something like if(songnum == i) is what you're looking for?

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You