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.

Recommended Answers

All 26 Replies

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,

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.

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);
     {
        [B]status = fgets(list, 80, inp);[/B]
          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.


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

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);

>> 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);

>> 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.

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);
}

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.

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.

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); 
}

:sad:

: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.

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); 
}

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);


}

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 ;
}

: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.

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]" .

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?

Okay, I've got it putting "*" on songs I choose. But it won't take them off if I rechoose them.

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++)
    {   
         select[songnum] = songnum;
         if(select[index] > 0)
          {
            printf("*");
                songnum = -1;
          }
          else
          {
              if(select[songnum] == 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);
}

Any tips? Also... the second if else statement seems to be doing nothing now, if that helps... somehow. You should see sort of were I was going with the second if else though.

What is the songnum[] array for?
What is in it when this function is started?

songnum is a variable, that's where my choice for a song is stored into it.

But I've solved all of that. My program works how I want it to, except for one thing.

When I add a song, I want it to add it to the right column, and do the time stuff, only if there is enough time left (remaining is bigger or equal to the time of the song). I have it so that it won't add it to the right column, and entering the number of the songs for the ones already on the right column does subtract the time, but the songs don't move back. I think know why they dont' move back. Because in a line of code I have it set so that it prints them on the right when the song's time is less than or equal to the remaining time.

But, one odd thing I've noticed, is that lets say I move the last three songs to the right, this will take up almost all the remaining time, only leaving 1:48. If I try to add another song bigger than that time, it won't add it, and it won't display it on the right, that's cool. However, when I try to remove songs from the right. It won't do it.

Like if I chose to remove one of them, it'll do the math right in the time displays, but the song will stay on the right. Why is that? If I enter the number again it will remove that song from the right, but it will subtract the time again. So I end up with -29:-22 and 79:22 which is way off. I don't know why this happens.

Here is the code. I know it's long, but the problem I is in the showTable function, I just put the whole thing so that you guys can see how it's all working. Thanks for all your help so far, this is the last thing I need to solve to have it running how I want to. I've got 3 days. :cheesy:

#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 song_count)
{
     FILE *inp;
     char list[99];
     int status;
     int number;
     inp = fopen("songdata.txt", "r");
     song_count = 1;
     
    status = fscanf(inp, "%d", &number);
     while(status != EOF)
     {      
          time[song_count] = number;
          fgets(list, 99, inp);  
          strncpy(names[song_count], list, 28);
          status = fscanf(inp, "%d", &number);
          song_count++;          
     }
   fclose(inp);
    return (song_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 remaining, int total_time)
{
     remaining = MAXTIME - total_time;
     return (remaining);
}

/*Table Display*/

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

/*Main Function Start*/

int main (void)
{   
    char names[99][STRSIZ]={"                              "};
    int time[99]={0};
    int select[99]={0};

    int sec, min, song_count, seconds, remaining, total_time, songnum, index;
     index = 1;
     songnum = -1;
     total_time = 0;
     while(songnum != SENTINEL)
     {
         song_count = fillTable(names, time, song_count);
          remaining = getRemainingTime(remaining, total_time);
          if(select[songnum] == 0)
          {
             if(time[songnum] > remaining)
                {
                    printf("**** Not enough remaining time for song #%d ****\n\n", songnum);
                     total_time = total_time;
                }
            else
                {   
                    total_time = total_time + time[songnum];
                }
          }
          else
          {
               total_time = total_time - time[songnum];
                /*select[songnum] = 0;*/
          }
                    
         showTable(time, names, select, song_count, min, sec, seconds, remaining, total_time, songnum);
         getRemainingTime(remaining, total_time);

         printf("\nSong number?\n");    
         scanf("%d", &songnum);
         printf("\n");
     } 
     return(0);
}

songnum is a variable, that's where my choice for a song is stored into it.

But I've solved all of that. My program works how I want it to, except for one thing.

When I add a song, I want it to add it to the right column, and do the time stuff, only if there is enough time left (remaining is bigger or equal to the time of the song). I have it so that it won't add it to the right column, and entering the number of the songs for the ones already on the right column does subtract the time, but the songs don't move back. I think know why they dont' move back. Because in a line of code I have it set so that it prints them on the right when the song's time is less than or equal to the remaining time.

But, one odd thing I've noticed, is that lets say I move the last three songs to the right, this will take up almost all the remaining time, only leaving 1:48. If I try to add another song bigger than that time, it won't add it, and it won't display it on the right, that's cool. However, when I try to remove songs from the right. It won't do it.

Like if I chose to remove one of them, it'll do the math right in the time displays, but the song will stay on the right. Why is that? If I enter the number again it will remove that song from the right, but it will subtract the time again. So I end up with -29:-22 and 79:22 which is way off. I don't know why this happens.

I find this description very confusing. An example whould be much clearer. Be sure to put the example(s) in CODE tags to to preserve your spacing.

Never mind guys I figured it out. :) Awesome, everything works how I want it to, great free weekend. Thanks for all your help.

place the data types into a struct it will be more organized
and do fread and fwrite and fseek and line it up so offset calculation for adderess maybe do more then 1 textfile

I think It should look like this

struct albumdata
{
char albumname[44];
char songname[44][44]; //should be a 3d array unless you know about vectors
struct songdata[44];
};

Thefunction
{
struct songdata sd[44];
int itsnotmyproject;
return whatagain?;
}


//That is my opinion at least

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.