1

So I am working on a program, I'm a net admin and terrible at programming, and need some help with structures, arrays, and possibly pointers. I am trying to write a program using struct, I know I need arrays but I am not sure how to properly tie them in with the struct. All info needs to be user input and needs to break on command to either skip to end or Loop back to certain point to enter more info. I need the user to input the employee ID#, then be able input multiple review scores, like 100, 90, 80, then break that sequence and either go back and enter another employee# and keep going, or skip to the end and print out all info entered.

The employee ID number and score entry seems to work fine when entering but when I print it out it does not look right so I am obviously doing something wrong with how the data is being stored and then printed. code and results below.

#include <stdio.h>

struct help{
    int empID;
    int marks[100];
    };
int main(){
    struct help s[100];
    int i, input, empNUM;

    NEWENTRY: printf("Enter employee ID#: ");
    scanf("%d", &empNUM);

    for(i=0;i<10;++i){
        s[i].empID = empNUM;
        printf("\nFor employee ID# %d\n",s[i].empID);

            while (i <= 100) {
                printf("Enter score:");

                if (scanf("%d", &input) == 1) {
                    if (input >= 0 && input <= 100) {
                        s[i].marks[100] = input;
                        i++;
                        }
                    else if (input == 101) {
                        printf("\n\nExiting entry.\n");
                        i = i - 1;
                        goto NEWENTRY;
                        }
                    else if (input == 102) {
                        printf("\n\nExiting entry.\n");
                        i = i - 1;
                        goto EXIT;
                        }
                    }
                }
            }
        EXIT:

        for(i=0;i<10;++i) {
            printf("\nInformation for employee ID number %d:\n",s[i].empID);
            printf("Marks: %.1f",s[i].marks);
            }

        return 0;
    }

Apologies, I forgot to add the pic

I would like it to look remotely like this if possible.

info for emp id 12345:
  100
  90
  80

info for emp id 67890:
  80
  90
  60
  • Where are the results? – MikeCAT Jun 24 '16 at 14:59
  • 4
    Do not access (no read nor write) `s[i].marks[100]`, which is out-of-range, or you will invoke *undefined behavior*. `printf("Marks: %.1f",s[i].marks)` will also invoke *undefined behavior* because `int*` is passed where `double` is expected. – MikeCAT Jun 24 '16 at 15:00
  • 2
    Also do not access `s[100]`, which is also out-of-range. – MikeCAT Jun 24 '16 at 15:03
  • 1
    Can you show an example of input and result – µtex Jun 24 '16 at 15:07
  • Not directly related, but all those `goto`s is terrible programming style. – Jabberwocky Jun 24 '16 at 15:14
  • 1
    Please show us an example of input and expected output. It's hard to guess what your program is actually supposed to do. – Jabberwocky Jun 24 '16 at 15:22
  • @MichaelWalz, although it's poor form to use a `goto` to roll your own loop, there's nothing wrong with using `goto` to break out of a multi-level loop nest. Doing so is usually much cleaner and clearer than the alternatives. – John Bollinger Jun 24 '16 at 15:25
  • I am a net admin, this got dumped on me so I am admittedly a very bad programmer. Any help and examples is greatly appreciated. – Philip Hudson Jun 24 '16 at 15:30
  • 3
    @PhilipHudson, it looks like you are getting confused by the fact that each element of your array of `structs` has a member that is also an array. You appear to want separate index variables for the two. If you want to access the `j`th mark given by the `i`th employee, that would be `s[i].marks[j]`. – John Bollinger Jun 24 '16 at 15:30
  • @PhilipHudson Do you want to make different scores for any particular #ID. And if score entered is out of range(input >= 0 && input <= 100), you need to enter another ID.. Just a guess – µtex Jun 24 '16 at 15:36
  • @JohnBollinger, ok so I understand about adding the `j`, but do both my struct ints need to be arrays? @sas the scores are 0-100, it's set up like that because a programmer friend from the military, who is now out of contact, helped me get this far, so if there is a better way to do it, I am open to anything. Using the `goto` was the only way I could figure out how to break out of the nested loops and get where I want to go. – Philip Hudson Jun 24 '16 at 15:44
  • @PhilipHudson, as far as I can tell, your `struct help` represents up to 100 individual marks given by a single employee. If that's what you intended, then it is correct for member `empId` to be a single `int`, and member `marks` to be an array. It is not inherently necessary for the `marks` arrays to have the same number of elements as array `s`, whose members are of type `struct help`; these are different, independent dimensions of your data, analogous to the `x` and `y` axes of a graph. – John Bollinger Jun 24 '16 at 16:48

1 Answers1

2

There are many problems in your code :

Problem 1 :

Here in your code,

you are using the same parameter i for the outer for loop and inner while loop :

for(i=0;i<10;++i) //you are using i here
{
    s[i].empID = empNUM;
    printf("\nFor employee ID# %d\n",s[i].empID);

        while (i <= 100) //and even here 
        {
            printf("Enter score:");

Problem 2 :

apart from that every time you goto NEWENTRY: and then again enter the for loop, i value is again set to 0,

so no matter how many entries you may enter, you will only populate the first element of struct array s i.e, s[0]


Problem 3:

you are using wrong arguments while printing your array here :

  printf("Marks: %.1f",s[i].marks);

here s[i].marks is of the type int*, you are using it to print a double data


Solution :

The simple solution I can give is that :

never usegoto (click to see why :) )

as it makes your code very complex to understand and more reasons can be known by clicking it.

you can instead achieve what you are trying to do without using goto this way:

#include <stdio.h>

struct help
{
    int empID;
    int marks[100];    
};
int main()
{
    struct help s[100];
    int i, j;   //useful for indices of array
    int val;    //useful for taking in user input
    int flag=0; //useful for exiting the program

    for(i=0;i<10;)
    {

        printf("Enter employee ID#: ");
        scanf("%d",&s[i].empID);

        printf("\nFor employee ID# %d\n",s[i].empID);

        for(j=0;j<100;j++)
        {
            printf("Enter score : ");
            scanf("%d",&val); //taking in score input

            if(val>=0 && val<=100)
            {
                s[i].marks[j]=val;
            }
            else if(val==101)
            {
                s[i].marks[j]=-1; //to mark the end of entries I used -1
                break;
            }
            else if(val==102)
            {
                s[i].marks[j]=-1;
                flag=1;            //to know whether user wants to exit
                break;
            }
            else
            {
                printf("\ninvalid entry\n");
                j--;
            }
        }

        printf("\n\n----------\n\n");

        i++;

        if(flag==1) //to exit
            break;
    }

    int num=i;

    for(i=0; i<num ; i++)
    {
        printf("\nInformation for employee ID number %d:\n",s[i].empID);
        for(j=0; s[i].marks[j]!=-1; j++)
            printf("Marks: %d\n",s[i].marks[j]);
    }

    printf("\nenter any key to exit!\n");
    scanf("%d",&i);

    return 0;
}

This logic is quite simple to understand :

  • the nested for loop I used is just like any other nested for loop used for populating a 2D array
  • in the inner for loop, val takes in the user's input and goes through an else if ladder

    • if val is between 0 and 100, it gets accepted and stored in marks array of s[i]
    • else-if val is 101, then -1 is inserted to mark the end of marks array of s[i] and you break out of inner for loop and i value is incremented
    • else-if val is 102, then similarly

      1. -1 is inserted to mark the end of marks array of s[i].
      2. additionally flag which has been 0 till now is assigned to 1 and this helps in exiting the outer for loop
    • else (that is for all other cases), the number is not accepted and j value is decremented to retake the value
  • and finally you print the scores of employees just as you print values 2D array and also using the fact that we assigned end of each marks array of s[i] with a -1.

Community
  • 1
  • 1
Cherubim
  • 5,287
  • 3
  • 20
  • 37
  • @PhilipHudson any doubts, feel free to ask :) – Cherubim Jun 24 '16 at 16:13
  • Just for my own information, where 101 and 102 do the breaks, is it possible to use a word in there? So instead of typing 101, you would type exit, and instead of 102, you would type quit. Or would that not work because they are char, or maybe strings? thank you – Philip Hudson Jun 24 '16 at 16:26
  • @PhilipHudson nope... because user's input is being taken into an integer `val`.. so an integer cannot store a word right :) – Cherubim Jun 24 '16 at 16:33
  • @PhilipHudson I understand what you want to achieve but that is a little complex... instead of taking in an integer as input you must use a string... hope you can work around with it.... but the best thing to do is just display at the starting of program using printf() that 101 is for new entry and 102 for printing results and exiting.. – Cherubim Jun 24 '16 at 16:36
  • 1
    That is what I did, adding the 101 102 at the beginning. Thank you for all your help. – Philip Hudson Jun 24 '16 at 17:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115551/discussion-between-philip-hudson-and-cherubim-anand). – Philip Hudson Jun 24 '16 at 18:21